Bash - pair each line of file












9















This question is strongly related to this and this question. I have a file that contains several lines where each line is a path to a file. Now I want to pair each line with each different line (not itself). Also a pair A B is equal to a B A pair for my purposes, so only one of these combinations should be produced.



Example



files.dat reads like this in a shorthand notation, each letter is a file path (absolute or relative)



a
b
c
d
e


Then my result should look something like this:



a b
a c
a d
a e
b c
b d
b e
c d
c e
d e


Preferrably I would like to solve this in bash. Unlike the other questions, my file list is rather small (about 200 lines), so using loops and RAM capacity
pose no problems.










share|improve this question









New contributor




Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • Does it have to be in bash proper, or just something available via the bash commandline? Other utilities are better positioned to process text.

    – Jeff Schaller
    2 days ago











  • @JeffSchaller Something accessible via the bash commandline. I was a bit unclear, sorry

    – Enno
    2 days ago













  • This is almost becoming a Code Golf :P

    – Richard de Wit
    yesterday






  • 1





    As a general rule, as long as you need to do something non-trivial, use your favourite scripting language over BASH. It will be less fragile (for example, against special characters or spaces), and much easier to expand whenever you need it (if you need three, or filter some of them away). Python or Perl should be installed in almost any Linux box, so they are good choices (unless you are working on embedded systems, like Busybox).

    – Davidmh
    yesterday
















9















This question is strongly related to this and this question. I have a file that contains several lines where each line is a path to a file. Now I want to pair each line with each different line (not itself). Also a pair A B is equal to a B A pair for my purposes, so only one of these combinations should be produced.



Example



files.dat reads like this in a shorthand notation, each letter is a file path (absolute or relative)



a
b
c
d
e


Then my result should look something like this:



a b
a c
a d
a e
b c
b d
b e
c d
c e
d e


Preferrably I would like to solve this in bash. Unlike the other questions, my file list is rather small (about 200 lines), so using loops and RAM capacity
pose no problems.










share|improve this question









New contributor




Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • Does it have to be in bash proper, or just something available via the bash commandline? Other utilities are better positioned to process text.

    – Jeff Schaller
    2 days ago











  • @JeffSchaller Something accessible via the bash commandline. I was a bit unclear, sorry

    – Enno
    2 days ago













  • This is almost becoming a Code Golf :P

    – Richard de Wit
    yesterday






  • 1





    As a general rule, as long as you need to do something non-trivial, use your favourite scripting language over BASH. It will be less fragile (for example, against special characters or spaces), and much easier to expand whenever you need it (if you need three, or filter some of them away). Python or Perl should be installed in almost any Linux box, so they are good choices (unless you are working on embedded systems, like Busybox).

    – Davidmh
    yesterday














9












9








9


0






This question is strongly related to this and this question. I have a file that contains several lines where each line is a path to a file. Now I want to pair each line with each different line (not itself). Also a pair A B is equal to a B A pair for my purposes, so only one of these combinations should be produced.



Example



files.dat reads like this in a shorthand notation, each letter is a file path (absolute or relative)



a
b
c
d
e


Then my result should look something like this:



a b
a c
a d
a e
b c
b d
b e
c d
c e
d e


Preferrably I would like to solve this in bash. Unlike the other questions, my file list is rather small (about 200 lines), so using loops and RAM capacity
pose no problems.










share|improve this question









New contributor




Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












This question is strongly related to this and this question. I have a file that contains several lines where each line is a path to a file. Now I want to pair each line with each different line (not itself). Also a pair A B is equal to a B A pair for my purposes, so only one of these combinations should be produced.



Example



files.dat reads like this in a shorthand notation, each letter is a file path (absolute or relative)



a
b
c
d
e


Then my result should look something like this:



a b
a c
a d
a e
b c
b d
b e
c d
c e
d e


Preferrably I would like to solve this in bash. Unlike the other questions, my file list is rather small (about 200 lines), so using loops and RAM capacity
pose no problems.







shell-script text-processing






share|improve this question









New contributor




Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 2 days ago









Jeff Schaller

43.5k1161140




43.5k1161140






New contributor




Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









EnnoEnno

1483




1483




New contributor




Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Enno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.













  • Does it have to be in bash proper, or just something available via the bash commandline? Other utilities are better positioned to process text.

    – Jeff Schaller
    2 days ago











  • @JeffSchaller Something accessible via the bash commandline. I was a bit unclear, sorry

    – Enno
    2 days ago













  • This is almost becoming a Code Golf :P

    – Richard de Wit
    yesterday






  • 1





    As a general rule, as long as you need to do something non-trivial, use your favourite scripting language over BASH. It will be less fragile (for example, against special characters or spaces), and much easier to expand whenever you need it (if you need three, or filter some of them away). Python or Perl should be installed in almost any Linux box, so they are good choices (unless you are working on embedded systems, like Busybox).

    – Davidmh
    yesterday



















  • Does it have to be in bash proper, or just something available via the bash commandline? Other utilities are better positioned to process text.

    – Jeff Schaller
    2 days ago











  • @JeffSchaller Something accessible via the bash commandline. I was a bit unclear, sorry

    – Enno
    2 days ago













  • This is almost becoming a Code Golf :P

    – Richard de Wit
    yesterday






  • 1





    As a general rule, as long as you need to do something non-trivial, use your favourite scripting language over BASH. It will be less fragile (for example, against special characters or spaces), and much easier to expand whenever you need it (if you need three, or filter some of them away). Python or Perl should be installed in almost any Linux box, so they are good choices (unless you are working on embedded systems, like Busybox).

    – Davidmh
    yesterday

















Does it have to be in bash proper, or just something available via the bash commandline? Other utilities are better positioned to process text.

– Jeff Schaller
2 days ago





Does it have to be in bash proper, or just something available via the bash commandline? Other utilities are better positioned to process text.

– Jeff Schaller
2 days ago













@JeffSchaller Something accessible via the bash commandline. I was a bit unclear, sorry

– Enno
2 days ago







@JeffSchaller Something accessible via the bash commandline. I was a bit unclear, sorry

– Enno
2 days ago















This is almost becoming a Code Golf :P

– Richard de Wit
yesterday





This is almost becoming a Code Golf :P

– Richard de Wit
yesterday




1




1





As a general rule, as long as you need to do something non-trivial, use your favourite scripting language over BASH. It will be less fragile (for example, against special characters or spaces), and much easier to expand whenever you need it (if you need three, or filter some of them away). Python or Perl should be installed in almost any Linux box, so they are good choices (unless you are working on embedded systems, like Busybox).

– Davidmh
yesterday





As a general rule, as long as you need to do something non-trivial, use your favourite scripting language over BASH. It will be less fragile (for example, against special characters or spaces), and much easier to expand whenever you need it (if you need three, or filter some of them away). Python or Perl should be installed in almost any Linux box, so they are good choices (unless you are working on embedded systems, like Busybox).

– Davidmh
yesterday










6 Answers
6






active

oldest

votes


















6














Use this command:



awk '{ name[$1]++ }
END { PROCINFO["sorted_in"] = "@ind_str_asc"
for (v1 in name) for (v2 in name) if (v1 < v2) print v1, v2 }
' files.dat


PROCINFO may be a gawk extension. 
If your awk doesn’t support it,
just leave out the PROCINFO["sorted_in"] = "@ind_str_asc" line
and pipe the output into sort (if you want the output sorted).



(This does not require the input to be sorted.)






share|improve this answer































    7














    $ join -j 2 -o 1.1,2.1 file file | awk '!seen[$1,$2]++ && !seen[$2,$1]++'
    a b
    a c
    a d
    a e
    b c
    b d
    b e
    c d
    c e
    d e


    This assumes that no line in the input file contains any whitespace. It also assumes that the file is sorted.



    The join command creates the full cross product of the lines in the file. It does this by joining the file with itself on a non-existing field. The non-standard -j 2 may be replaced by -1 2 -2 2 (but not by -j2 unless you use GNU join).



    The awk command reads the result of this and only outputs results that are pairs that has not yet been seen.






    share|improve this answer


























    • What do you mean by "the file is sorted"? Sorted by which criteria?

      – Enno
      2 days ago











    • @Enno Sorted the way sort -b would sort it. join require sorted input files.

      – Kusalananda
      2 days ago





















    7














    A python solution.
    The input file is fed to itertools.combinations from the standard library, which generates 2-length tuples that are formatted and printed to standard output.



    python3 -c 'from itertools import combinations
    with open("file") as f:
    lines = (line.rstrip() for line in f)
    lines = ("{} {}".format(x, y) for x, y in combinations(lines, 2))
    print(*lines, sep="n")
    '





    share|improve this answer































      6














      If you have ruby installed:



      $ ruby -0777 -F'n' -lane '$F.combination(2) { |c| puts c.join(" ")}' ip.txt
      a b
      a c
      a d
      a e
      b c
      b d
      b e
      c d
      c e
      d e




      • -0777 slurp entire file (should be okay as it is mentioned in OP that file size is small)


      • -F'n' split based on newline, so each line will be an element in $F array


      • $F.combination(2) generate combinations 2 elements at a time


      • { |c| puts c.join(" ")} print as required

      • if input file can contain duplicates, use $F.uniq.combination(2)




      for 3 elements at a time:



      $ ruby -0777 -F'n' -lane '$F.combination(3) { |c| puts c.join(" ")}' ip.txt
      a b c
      a b d
      a b e
      a c d
      a c e
      a d e
      b c d
      b c e
      b d e
      c d e





      With perl (not generic)



      $ perl -0777 -F'n' -lane 'for $i (0..$#F) {
      for $j ($i+1..$#F) {
      print "$F[$i] $F[$j]n" } }' ip.txt
      a b
      a c
      a d
      a e
      b c
      b d
      b e
      c d
      c e
      d e




      With awk



      $ awk '{ a[NR]=$0 }
      END{ for(i=1;i<=NR;i++)
      for(j=i+1;j<=NR;j++)
      print a[i], a[j] }' ip.txt
      a b
      a c
      a d
      a e
      b c
      b d
      b e
      c d
      c e
      d e





      share|improve this answer

































        3














        Here's one in pure shell.



        test $# -gt 1 || exit
        a=$1
        shift
        for f in "$@"
        do
        echo $a $f
        done
        exec /bin/sh $0 "$@"


        Example:



        ~ (137) $ sh test.sh $(cat file.dat)
        a b
        a c
        a d
        a e
        b c
        b d
        b e
        c d
        c e
        d e
        ~ (138) $





        share|improve this answer










        New contributor




        EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.
















        • 1





          Command substitution strips trailing newlines, so you're better off with something like <file.dat xargs test.sh than test.sh $(cat file.dat)

          – iruvar
          2 days ago



















        0














        Using Perl we can do it as shown:



        $ perl -lne '
        push @A, $_}{
        while ( @A ) {
        my $e = shift @A;
        print "$e $_" for @A;
        }
        ' input.txt





        share|improve this answer























          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "106"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Enno is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f506815%2fbash-pair-each-line-of-file%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          6 Answers
          6






          active

          oldest

          votes








          6 Answers
          6






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          6














          Use this command:



          awk '{ name[$1]++ }
          END { PROCINFO["sorted_in"] = "@ind_str_asc"
          for (v1 in name) for (v2 in name) if (v1 < v2) print v1, v2 }
          ' files.dat


          PROCINFO may be a gawk extension. 
          If your awk doesn’t support it,
          just leave out the PROCINFO["sorted_in"] = "@ind_str_asc" line
          and pipe the output into sort (if you want the output sorted).



          (This does not require the input to be sorted.)






          share|improve this answer




























            6














            Use this command:



            awk '{ name[$1]++ }
            END { PROCINFO["sorted_in"] = "@ind_str_asc"
            for (v1 in name) for (v2 in name) if (v1 < v2) print v1, v2 }
            ' files.dat


            PROCINFO may be a gawk extension. 
            If your awk doesn’t support it,
            just leave out the PROCINFO["sorted_in"] = "@ind_str_asc" line
            and pipe the output into sort (if you want the output sorted).



            (This does not require the input to be sorted.)






            share|improve this answer


























              6












              6








              6







              Use this command:



              awk '{ name[$1]++ }
              END { PROCINFO["sorted_in"] = "@ind_str_asc"
              for (v1 in name) for (v2 in name) if (v1 < v2) print v1, v2 }
              ' files.dat


              PROCINFO may be a gawk extension. 
              If your awk doesn’t support it,
              just leave out the PROCINFO["sorted_in"] = "@ind_str_asc" line
              and pipe the output into sort (if you want the output sorted).



              (This does not require the input to be sorted.)






              share|improve this answer













              Use this command:



              awk '{ name[$1]++ }
              END { PROCINFO["sorted_in"] = "@ind_str_asc"
              for (v1 in name) for (v2 in name) if (v1 < v2) print v1, v2 }
              ' files.dat


              PROCINFO may be a gawk extension. 
              If your awk doesn’t support it,
              just leave out the PROCINFO["sorted_in"] = "@ind_str_asc" line
              and pipe the output into sort (if you want the output sorted).



              (This does not require the input to be sorted.)







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 2 days ago









              G-ManG-Man

              13.5k93768




              13.5k93768

























                  7














                  $ join -j 2 -o 1.1,2.1 file file | awk '!seen[$1,$2]++ && !seen[$2,$1]++'
                  a b
                  a c
                  a d
                  a e
                  b c
                  b d
                  b e
                  c d
                  c e
                  d e


                  This assumes that no line in the input file contains any whitespace. It also assumes that the file is sorted.



                  The join command creates the full cross product of the lines in the file. It does this by joining the file with itself on a non-existing field. The non-standard -j 2 may be replaced by -1 2 -2 2 (but not by -j2 unless you use GNU join).



                  The awk command reads the result of this and only outputs results that are pairs that has not yet been seen.






                  share|improve this answer


























                  • What do you mean by "the file is sorted"? Sorted by which criteria?

                    – Enno
                    2 days ago











                  • @Enno Sorted the way sort -b would sort it. join require sorted input files.

                    – Kusalananda
                    2 days ago


















                  7














                  $ join -j 2 -o 1.1,2.1 file file | awk '!seen[$1,$2]++ && !seen[$2,$1]++'
                  a b
                  a c
                  a d
                  a e
                  b c
                  b d
                  b e
                  c d
                  c e
                  d e


                  This assumes that no line in the input file contains any whitespace. It also assumes that the file is sorted.



                  The join command creates the full cross product of the lines in the file. It does this by joining the file with itself on a non-existing field. The non-standard -j 2 may be replaced by -1 2 -2 2 (but not by -j2 unless you use GNU join).



                  The awk command reads the result of this and only outputs results that are pairs that has not yet been seen.






                  share|improve this answer


























                  • What do you mean by "the file is sorted"? Sorted by which criteria?

                    – Enno
                    2 days ago











                  • @Enno Sorted the way sort -b would sort it. join require sorted input files.

                    – Kusalananda
                    2 days ago
















                  7












                  7








                  7







                  $ join -j 2 -o 1.1,2.1 file file | awk '!seen[$1,$2]++ && !seen[$2,$1]++'
                  a b
                  a c
                  a d
                  a e
                  b c
                  b d
                  b e
                  c d
                  c e
                  d e


                  This assumes that no line in the input file contains any whitespace. It also assumes that the file is sorted.



                  The join command creates the full cross product of the lines in the file. It does this by joining the file with itself on a non-existing field. The non-standard -j 2 may be replaced by -1 2 -2 2 (but not by -j2 unless you use GNU join).



                  The awk command reads the result of this and only outputs results that are pairs that has not yet been seen.






                  share|improve this answer















                  $ join -j 2 -o 1.1,2.1 file file | awk '!seen[$1,$2]++ && !seen[$2,$1]++'
                  a b
                  a c
                  a d
                  a e
                  b c
                  b d
                  b e
                  c d
                  c e
                  d e


                  This assumes that no line in the input file contains any whitespace. It also assumes that the file is sorted.



                  The join command creates the full cross product of the lines in the file. It does this by joining the file with itself on a non-existing field. The non-standard -j 2 may be replaced by -1 2 -2 2 (but not by -j2 unless you use GNU join).



                  The awk command reads the result of this and only outputs results that are pairs that has not yet been seen.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 2 days ago

























                  answered 2 days ago









                  KusalanandaKusalananda

                  136k17257426




                  136k17257426













                  • What do you mean by "the file is sorted"? Sorted by which criteria?

                    – Enno
                    2 days ago











                  • @Enno Sorted the way sort -b would sort it. join require sorted input files.

                    – Kusalananda
                    2 days ago





















                  • What do you mean by "the file is sorted"? Sorted by which criteria?

                    – Enno
                    2 days ago











                  • @Enno Sorted the way sort -b would sort it. join require sorted input files.

                    – Kusalananda
                    2 days ago



















                  What do you mean by "the file is sorted"? Sorted by which criteria?

                  – Enno
                  2 days ago





                  What do you mean by "the file is sorted"? Sorted by which criteria?

                  – Enno
                  2 days ago













                  @Enno Sorted the way sort -b would sort it. join require sorted input files.

                  – Kusalananda
                  2 days ago







                  @Enno Sorted the way sort -b would sort it. join require sorted input files.

                  – Kusalananda
                  2 days ago













                  7














                  A python solution.
                  The input file is fed to itertools.combinations from the standard library, which generates 2-length tuples that are formatted and printed to standard output.



                  python3 -c 'from itertools import combinations
                  with open("file") as f:
                  lines = (line.rstrip() for line in f)
                  lines = ("{} {}".format(x, y) for x, y in combinations(lines, 2))
                  print(*lines, sep="n")
                  '





                  share|improve this answer




























                    7














                    A python solution.
                    The input file is fed to itertools.combinations from the standard library, which generates 2-length tuples that are formatted and printed to standard output.



                    python3 -c 'from itertools import combinations
                    with open("file") as f:
                    lines = (line.rstrip() for line in f)
                    lines = ("{} {}".format(x, y) for x, y in combinations(lines, 2))
                    print(*lines, sep="n")
                    '





                    share|improve this answer


























                      7












                      7








                      7







                      A python solution.
                      The input file is fed to itertools.combinations from the standard library, which generates 2-length tuples that are formatted and printed to standard output.



                      python3 -c 'from itertools import combinations
                      with open("file") as f:
                      lines = (line.rstrip() for line in f)
                      lines = ("{} {}".format(x, y) for x, y in combinations(lines, 2))
                      print(*lines, sep="n")
                      '





                      share|improve this answer













                      A python solution.
                      The input file is fed to itertools.combinations from the standard library, which generates 2-length tuples that are formatted and printed to standard output.



                      python3 -c 'from itertools import combinations
                      with open("file") as f:
                      lines = (line.rstrip() for line in f)
                      lines = ("{} {}".format(x, y) for x, y in combinations(lines, 2))
                      print(*lines, sep="n")
                      '






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered 2 days ago









                      iruvariruvar

                      12.2k63062




                      12.2k63062























                          6














                          If you have ruby installed:



                          $ ruby -0777 -F'n' -lane '$F.combination(2) { |c| puts c.join(" ")}' ip.txt
                          a b
                          a c
                          a d
                          a e
                          b c
                          b d
                          b e
                          c d
                          c e
                          d e




                          • -0777 slurp entire file (should be okay as it is mentioned in OP that file size is small)


                          • -F'n' split based on newline, so each line will be an element in $F array


                          • $F.combination(2) generate combinations 2 elements at a time


                          • { |c| puts c.join(" ")} print as required

                          • if input file can contain duplicates, use $F.uniq.combination(2)




                          for 3 elements at a time:



                          $ ruby -0777 -F'n' -lane '$F.combination(3) { |c| puts c.join(" ")}' ip.txt
                          a b c
                          a b d
                          a b e
                          a c d
                          a c e
                          a d e
                          b c d
                          b c e
                          b d e
                          c d e





                          With perl (not generic)



                          $ perl -0777 -F'n' -lane 'for $i (0..$#F) {
                          for $j ($i+1..$#F) {
                          print "$F[$i] $F[$j]n" } }' ip.txt
                          a b
                          a c
                          a d
                          a e
                          b c
                          b d
                          b e
                          c d
                          c e
                          d e




                          With awk



                          $ awk '{ a[NR]=$0 }
                          END{ for(i=1;i<=NR;i++)
                          for(j=i+1;j<=NR;j++)
                          print a[i], a[j] }' ip.txt
                          a b
                          a c
                          a d
                          a e
                          b c
                          b d
                          b e
                          c d
                          c e
                          d e





                          share|improve this answer






























                            6














                            If you have ruby installed:



                            $ ruby -0777 -F'n' -lane '$F.combination(2) { |c| puts c.join(" ")}' ip.txt
                            a b
                            a c
                            a d
                            a e
                            b c
                            b d
                            b e
                            c d
                            c e
                            d e




                            • -0777 slurp entire file (should be okay as it is mentioned in OP that file size is small)


                            • -F'n' split based on newline, so each line will be an element in $F array


                            • $F.combination(2) generate combinations 2 elements at a time


                            • { |c| puts c.join(" ")} print as required

                            • if input file can contain duplicates, use $F.uniq.combination(2)




                            for 3 elements at a time:



                            $ ruby -0777 -F'n' -lane '$F.combination(3) { |c| puts c.join(" ")}' ip.txt
                            a b c
                            a b d
                            a b e
                            a c d
                            a c e
                            a d e
                            b c d
                            b c e
                            b d e
                            c d e





                            With perl (not generic)



                            $ perl -0777 -F'n' -lane 'for $i (0..$#F) {
                            for $j ($i+1..$#F) {
                            print "$F[$i] $F[$j]n" } }' ip.txt
                            a b
                            a c
                            a d
                            a e
                            b c
                            b d
                            b e
                            c d
                            c e
                            d e




                            With awk



                            $ awk '{ a[NR]=$0 }
                            END{ for(i=1;i<=NR;i++)
                            for(j=i+1;j<=NR;j++)
                            print a[i], a[j] }' ip.txt
                            a b
                            a c
                            a d
                            a e
                            b c
                            b d
                            b e
                            c d
                            c e
                            d e





                            share|improve this answer




























                              6












                              6








                              6







                              If you have ruby installed:



                              $ ruby -0777 -F'n' -lane '$F.combination(2) { |c| puts c.join(" ")}' ip.txt
                              a b
                              a c
                              a d
                              a e
                              b c
                              b d
                              b e
                              c d
                              c e
                              d e




                              • -0777 slurp entire file (should be okay as it is mentioned in OP that file size is small)


                              • -F'n' split based on newline, so each line will be an element in $F array


                              • $F.combination(2) generate combinations 2 elements at a time


                              • { |c| puts c.join(" ")} print as required

                              • if input file can contain duplicates, use $F.uniq.combination(2)




                              for 3 elements at a time:



                              $ ruby -0777 -F'n' -lane '$F.combination(3) { |c| puts c.join(" ")}' ip.txt
                              a b c
                              a b d
                              a b e
                              a c d
                              a c e
                              a d e
                              b c d
                              b c e
                              b d e
                              c d e





                              With perl (not generic)



                              $ perl -0777 -F'n' -lane 'for $i (0..$#F) {
                              for $j ($i+1..$#F) {
                              print "$F[$i] $F[$j]n" } }' ip.txt
                              a b
                              a c
                              a d
                              a e
                              b c
                              b d
                              b e
                              c d
                              c e
                              d e




                              With awk



                              $ awk '{ a[NR]=$0 }
                              END{ for(i=1;i<=NR;i++)
                              for(j=i+1;j<=NR;j++)
                              print a[i], a[j] }' ip.txt
                              a b
                              a c
                              a d
                              a e
                              b c
                              b d
                              b e
                              c d
                              c e
                              d e





                              share|improve this answer















                              If you have ruby installed:



                              $ ruby -0777 -F'n' -lane '$F.combination(2) { |c| puts c.join(" ")}' ip.txt
                              a b
                              a c
                              a d
                              a e
                              b c
                              b d
                              b e
                              c d
                              c e
                              d e




                              • -0777 slurp entire file (should be okay as it is mentioned in OP that file size is small)


                              • -F'n' split based on newline, so each line will be an element in $F array


                              • $F.combination(2) generate combinations 2 elements at a time


                              • { |c| puts c.join(" ")} print as required

                              • if input file can contain duplicates, use $F.uniq.combination(2)




                              for 3 elements at a time:



                              $ ruby -0777 -F'n' -lane '$F.combination(3) { |c| puts c.join(" ")}' ip.txt
                              a b c
                              a b d
                              a b e
                              a c d
                              a c e
                              a d e
                              b c d
                              b c e
                              b d e
                              c d e





                              With perl (not generic)



                              $ perl -0777 -F'n' -lane 'for $i (0..$#F) {
                              for $j ($i+1..$#F) {
                              print "$F[$i] $F[$j]n" } }' ip.txt
                              a b
                              a c
                              a d
                              a e
                              b c
                              b d
                              b e
                              c d
                              c e
                              d e




                              With awk



                              $ awk '{ a[NR]=$0 }
                              END{ for(i=1;i<=NR;i++)
                              for(j=i+1;j<=NR;j++)
                              print a[i], a[j] }' ip.txt
                              a b
                              a c
                              a d
                              a e
                              b c
                              b d
                              b e
                              c d
                              c e
                              d e






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited 2 days ago

























                              answered 2 days ago









                              SundeepSundeep

                              7,4811927




                              7,4811927























                                  3














                                  Here's one in pure shell.



                                  test $# -gt 1 || exit
                                  a=$1
                                  shift
                                  for f in "$@"
                                  do
                                  echo $a $f
                                  done
                                  exec /bin/sh $0 "$@"


                                  Example:



                                  ~ (137) $ sh test.sh $(cat file.dat)
                                  a b
                                  a c
                                  a d
                                  a e
                                  b c
                                  b d
                                  b e
                                  c d
                                  c e
                                  d e
                                  ~ (138) $





                                  share|improve this answer










                                  New contributor




                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.
















                                  • 1





                                    Command substitution strips trailing newlines, so you're better off with something like <file.dat xargs test.sh than test.sh $(cat file.dat)

                                    – iruvar
                                    2 days ago
















                                  3














                                  Here's one in pure shell.



                                  test $# -gt 1 || exit
                                  a=$1
                                  shift
                                  for f in "$@"
                                  do
                                  echo $a $f
                                  done
                                  exec /bin/sh $0 "$@"


                                  Example:



                                  ~ (137) $ sh test.sh $(cat file.dat)
                                  a b
                                  a c
                                  a d
                                  a e
                                  b c
                                  b d
                                  b e
                                  c d
                                  c e
                                  d e
                                  ~ (138) $





                                  share|improve this answer










                                  New contributor




                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.
















                                  • 1





                                    Command substitution strips trailing newlines, so you're better off with something like <file.dat xargs test.sh than test.sh $(cat file.dat)

                                    – iruvar
                                    2 days ago














                                  3












                                  3








                                  3







                                  Here's one in pure shell.



                                  test $# -gt 1 || exit
                                  a=$1
                                  shift
                                  for f in "$@"
                                  do
                                  echo $a $f
                                  done
                                  exec /bin/sh $0 "$@"


                                  Example:



                                  ~ (137) $ sh test.sh $(cat file.dat)
                                  a b
                                  a c
                                  a d
                                  a e
                                  b c
                                  b d
                                  b e
                                  c d
                                  c e
                                  d e
                                  ~ (138) $





                                  share|improve this answer










                                  New contributor




                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.










                                  Here's one in pure shell.



                                  test $# -gt 1 || exit
                                  a=$1
                                  shift
                                  for f in "$@"
                                  do
                                  echo $a $f
                                  done
                                  exec /bin/sh $0 "$@"


                                  Example:



                                  ~ (137) $ sh test.sh $(cat file.dat)
                                  a b
                                  a c
                                  a d
                                  a e
                                  b c
                                  b d
                                  b e
                                  c d
                                  c e
                                  d e
                                  ~ (138) $






                                  share|improve this answer










                                  New contributor




                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.









                                  share|improve this answer



                                  share|improve this answer








                                  edited yesterday





















                                  New contributor




                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.









                                  answered 2 days ago









                                  EdCEdC

                                  312




                                  312




                                  New contributor




                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.





                                  New contributor





                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.






                                  EdC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.








                                  • 1





                                    Command substitution strips trailing newlines, so you're better off with something like <file.dat xargs test.sh than test.sh $(cat file.dat)

                                    – iruvar
                                    2 days ago














                                  • 1





                                    Command substitution strips trailing newlines, so you're better off with something like <file.dat xargs test.sh than test.sh $(cat file.dat)

                                    – iruvar
                                    2 days ago








                                  1




                                  1





                                  Command substitution strips trailing newlines, so you're better off with something like <file.dat xargs test.sh than test.sh $(cat file.dat)

                                  – iruvar
                                  2 days ago





                                  Command substitution strips trailing newlines, so you're better off with something like <file.dat xargs test.sh than test.sh $(cat file.dat)

                                  – iruvar
                                  2 days ago











                                  0














                                  Using Perl we can do it as shown:



                                  $ perl -lne '
                                  push @A, $_}{
                                  while ( @A ) {
                                  my $e = shift @A;
                                  print "$e $_" for @A;
                                  }
                                  ' input.txt





                                  share|improve this answer




























                                    0














                                    Using Perl we can do it as shown:



                                    $ perl -lne '
                                    push @A, $_}{
                                    while ( @A ) {
                                    my $e = shift @A;
                                    print "$e $_" for @A;
                                    }
                                    ' input.txt





                                    share|improve this answer


























                                      0












                                      0








                                      0







                                      Using Perl we can do it as shown:



                                      $ perl -lne '
                                      push @A, $_}{
                                      while ( @A ) {
                                      my $e = shift @A;
                                      print "$e $_" for @A;
                                      }
                                      ' input.txt





                                      share|improve this answer













                                      Using Perl we can do it as shown:



                                      $ perl -lne '
                                      push @A, $_}{
                                      while ( @A ) {
                                      my $e = shift @A;
                                      print "$e $_" for @A;
                                      }
                                      ' input.txt






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered 2 days ago









                                      Rakesh SharmaRakesh Sharma

                                      342115




                                      342115






















                                          Enno is a new contributor. Be nice, and check out our Code of Conduct.










                                          draft saved

                                          draft discarded


















                                          Enno is a new contributor. Be nice, and check out our Code of Conduct.













                                          Enno is a new contributor. Be nice, and check out our Code of Conduct.












                                          Enno is a new contributor. Be nice, and check out our Code of Conduct.
















                                          Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f506815%2fbash-pair-each-line-of-file%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                                          Alcedinidae

                                          Origin of the phrase “under your belt”?