2

I'm trying to be a bit effective and need a script or command solution.

Say I make a file with 2 columns, or two files with one column, whichever is easier:

AA1 B2        ZZ1 YYY XX1
AA2 B2        ZZ2 YYY XX2
AA3 B3        ZZ3 YYY XX3
AA4 B4        ZZ4 YYY XX4
              ZZ5 YYY XX5
              ZZ6 YYY XX6
              ZZ7 YYY XX7

There is an uneven number of entries. Now, I want to make a new file (preferably with some other input as well, though lets start here) that takes every value in the first column and combines that with every value in the second column (they will always have unequal number of lines) and outputs results as:

AA1 B2 ZZ1 YYY XX1
AA1 B2 ZZ2 YYY XX2
[...]
AA4 B4 ZZ1 YYY XX1
AA4 B4 ZZ2 YYY XX2

So, cycle through all values in column 1 in order, combining them with each value in column 2 in order.

  • Please edit your question and clarify what your input is. I'm not sure if you're showing one file with 4 columns, one file with 2 columns each of whose fields includes a space or two separate files. – terdon Nov 20 '15 at 14:06
1

Assuming you have the following files:

$ cat file1
ZZ1 YYY XX1
ZZ2 YYY XX2
ZZ3 YYY XX3
ZZ4 YYY XX4
ZZ5 YYY XX5
ZZ6 YYY XX6
ZZ7 YYY XX7
$ cat file2
AA1 B2
AA2 B2
AA3 B3
AA4 B4

Then use this awk:

awk 'FNR==NR{a[c++]=$0} FNR!=NR{for(i in a){print $0,a[i]}}' file1 file2
  • FNR==NR applies only to the first file file1
    • a[c++]=$0 fills an array called a with the contents of file1
  • FNR!=NR applies only to the second file file2
    • for(i in a) loops trough array a...
    • print $0,a[i] ...and print the line from file2 and the contents of the array.

The outout:

AA1 B2 ZZ1 YYY XX1
AA1 B2 ZZ2 YYY XX2
AA1 B2 ZZ3 YYY XX3
AA1 B2 ZZ4 YYY XX4
AA1 B2 ZZ5 YYY XX5
AA1 B2 ZZ6 YYY XX6
AA1 B2 ZZ7 YYY XX7
AA2 B2 ZZ1 YYY XX1
AA2 B2 ZZ2 YYY XX2
AA2 B2 ZZ3 YYY XX3
AA2 B2 ZZ4 YYY XX4
AA2 B2 ZZ5 YYY XX5
AA2 B2 ZZ6 YYY XX6
AA2 B2 ZZ7 YYY XX7
AA3 B3 ZZ1 YYY XX1
AA3 B3 ZZ2 YYY XX2
AA3 B3 ZZ3 YYY XX3
AA3 B3 ZZ4 YYY XX4
AA3 B3 ZZ5 YYY XX5
AA3 B3 ZZ6 YYY XX6
AA3 B3 ZZ7 YYY XX7
AA4 B4 ZZ1 YYY XX1
AA4 B4 ZZ2 YYY XX2
AA4 B4 ZZ3 YYY XX3
AA4 B4 ZZ4 YYY XX4
AA4 B4 ZZ5 YYY XX5
AA4 B4 ZZ6 YYY XX6
AA4 B4 ZZ7 YYY XX7

0

Since your values have spaces in them it would be easier to have the two columns in separate files. Then you could do something like:

IFS='
'
for a in $(cat file1); do
  for b in $(cat file2); do
     echo "$a $b" > file3;
  done
done

It's not the most efficient since it has to read in file2 in its entirety for every line in file1 but it would get the job done.

  • see this and this – iruvar Nov 20 '15 at 14:55
  • The biggest reason the first link could give for not using a for loop is that it collapses consecutive delimiters (in this case newlines). For the OP this is desirable behavior. The second link just provides alternatives to my solution. Why not post your own answer with those options or flag the question as a duplicate? – David King Nov 20 '15 at 15:11
  • A bigger problem with for a in $(cat file1) is that the $(cat file) command substitution forces the shell to load the contents of the file into memory – iruvar Nov 20 '15 at 15:17
  • It does but for file sizes like what were mentioned that shouldn't be an issue. In fact the files can get quite large without causing an issue. – David King Nov 20 '15 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.