Search code examples
bashloopsnestedtriangularoneway

Bash: nested loop one way comparison


I have one queston about nested loop with bash.

I have an input files with one file name per line (full path) I read this file and then i make a nest loop:

    for i in $filelines ; do
    echo $i
    for j in $filelines ; do
         ./program $i $j
    done
done

The program I within the loop is pretty low. Basically it compare the file A with the file B.

I want to skip A vs A comparison (i.e comparing one file with itslef) AND I want to avoid permutation (i.e. for file A and B, only perform A against B and not B against A).

What is the simplest to perform this?


Solution

  • Version 2: this one takes care of permutations

    #!/bin/bash
    
    tmpunsorted="/tmp/compare_unsorted"
    tmpsorted="/tmp/compare_sorted"
    
    >$tmpunsorted
    
    while read linei
    do
        while read linej
        do
            if [ $linei != $linej ]
            then
                echo $linei $linej | tr " " "\n" | sort | tr "\n" " " >>$tmpunsorted
                echo >>$tmpunsorted
            fi
        done <filelines
    done <filelines
    
    sort $tmpunsorted | uniq > $tmpsorted
    
    while read linecompare
    do
        echo "./program $linecompare"
    done <$tmpsorted
    
    # Cleanup
    rm -f $tmpunsorted
    rm -f $tmpsorted
    

    What is done here:

    • I use the while loop to read each line, twice, i and j
    • if the value of the lines is the same, forget them, no use to consider them
    • if they are different, output them into a file ($tmpunsorted). And they are sorted in alphebetical order before going tothe $tmpunsorted file. This way the arguments are always in the same order. So a b and b a will be same in the unsorted file.
    • I then apply sort | uniq on $tmpunsorted, so the result is a list of individual argument pairs.
    • finally loop on the $tmpsorted file, and call the program on each individual pair.
    • Since I do not have your program, I did an echo, which you should remove to use the script.