3

I know how to merge two tables to print alternative lines in a new file, but I want to merge every two lines from file1.txt with one line from file2.txt. As an example:

file1.txt is

A a aa
B b bb 
C c cc
D d dd

and file2.txt is

E e ee 
F f ff

I want to have

A a aa
B b bb 
E e ee 
C c cc
D d dd
F f ff
  • you want the same order u mentioned?? A, B, E, C, D, F?? – YuganTej Nov 25 '18 at 7:00
  • 1
    What to do if lines amount in file1.txt smaller than amount in file2.txt ? – mature Nov 25 '18 at 8:27
  • Please help us help you by answering our questions :-) It is best to answer our questions by editing your original question: "Edit 1: ...; Edit 2: ..." – sudodus Nov 25 '18 at 10:00
  • @PRATAP yes, I want the same order of my example. – Negar Nov 26 '18 at 0:12
7

Using GNU sed, you can read and insert one line from the second file after every other line ("two skip two") of the first:

$ sed '2~2R file2.txt' file1.txt
A a aa
B b bb 
E e ee 
C c cc
D d dd
F f ff

Slightly more long-winded implementation of the same in awk:

awk '{print} !(NR%2) {if ((getline < "file2.txt") > -1) print}' file1.txt
6

You can use the paste command for this:

% paste -d '\n' - - file2.txt < file1.txt
A a aa
B b bb 
E e ee 
C c cc
D d dd
F f ff

paste, by default, takes lines from each input file, then merges them into a single line separated by tabs. Using -d '\n', we tell it to use newlines as the separator instead. - is standard input, which is redirected in from file1.txt (< file1.txt). So paste takes one line from standard input, then another line from standard input (effectively two lines from file1.txt, then a line from file2.txt and prints them out separated by newlines.

  • It works! thanks. but, If two files have different number of columns, it prints blanket lines. how can I solve it? – Negar Nov 25 '18 at 8:39
  • 1
    Can you update your post with such an example? – muru Nov 25 '18 at 8:55
  • 1
    @Negar, do you mean different number of columns or 'not matching number of lines'? And what action do you want in such cases (when the files do not match)? – sudodus Nov 25 '18 at 9:51
  • @Negar columns or rows? Again, please post a relevant example in your question. – muru Nov 26 '18 at 0:23
  • 1
    @ sudodus Assume file1 has 30 rows and file2 has 10 rows. Then I want tho have a file including 40 rows. I want to have the first 20 rows alternatively plus final 20 rows of file1 – Negar Nov 26 '18 at 2:52
2

Original shellscript

I thought the following shellscript would do it. The trick is to open the two files on separate file descriptors (here #4 and #5).

#!/bin/bash

while read -r -u 4 line1 && read -r -u 4 line2 && read -r -u 5 line3
do
  echo "$line1"
  echo "$line2"
  echo "$line3"
done 4<file1.txt 5<file2.txt

Test

Make the shellscript executable and run it,

$ ./myscript 
A a aa
B b bb
E e ee
C c cc
D d dd
F f ff

The original shellscript stops, when reading to the end of file in one of the input files (so that only matching 2+1 lines are written to the output).

Modified shellscript

The following shellscript will continue reading and writing until all the files have reached end of file (so that all available lines are written to the output). This should match what the OP wants.

#!/bin/bash

end1=false
end2=false
cont=true
while $cont
do
 read -r -u 4 line1
 if [ $? -eq 0 ]
 then
  echo "$line1"
 else
  end1=true
 fi

 read -r -u 4 line2
 if [ $? -eq 0 ]
 then
  echo "$line2"
 else
  end1=true
 fi

 read -r -u 5 line3
 if [ $? -eq 0 ]
 then
  echo "$line3"
 else
  end2=true
 fi

 if $end1 && $end2  # modify this line to change when to stop
 then
  cont=false
 fi
done 4<file1.txt 5<file2.txt

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.