5

I have two files and I am trying to insert a line from file2 into file1 every other 4 lines starting at the beginning of file1. So for example:

file1:

line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10

file2:

50
43
21

output I am trying to get:

50
line 1
line 2
line 3
line 4
43
line 5
line 6
line 7
line 8
21
line 9
line 10

The code I have:

while read line
do
    sed '0~4 s/$/$line/g' < file1.txt > file2.txt
done < file1.txt

I am getting the following error:

sed: 1: "0~4 s/$/$line/g": invalid command code ~
anubhava
  • 761,203
  • 64
  • 569
  • 643
jeabesli
  • 83
  • 1
  • 1
  • 7

5 Answers5

2

It is easing to do this using awk:

awk 'FNR==NR{a[i++]=$0; next} !((FNR-1) % 4){print a[j++]} 1' file2 file1

50
line 1
line 2
line 3
line 4
43
line 5
line 6
line 7
line 8
21
line 9
line 10
  • While processing first file in input i.e. file2, we store each line in array with key as an incrementing number starting with 0.
  • While processing second file in input i.e. file1, we check if current record # is divisible by 4 using modulo arithmetic and if it is then insert a line from file2 and increment the index counter.
  • Finally using action 1, we print lines from file1.
anubhava
  • 761,203
  • 64
  • 569
  • 643
2

The following steps through both files without loading either one into an array in memory:

awk '(NR-1)%4==0{getline this<"file2";print this} 1' file1

This might be preferable if your actual file2 is larger than what you want to hold in memory.

This breaks down as follows:

  • (NR-1)%4==0 - a condition which matches every 4th line starting at 0
  • getline this<"file2" - gets a line from "file2" and stores it in the variable this
  • print this - prints ... this.
  • 1 - shorthand for "print the current line", which in this case comes from file1 (awk's normal input)
ghoti
  • 45,319
  • 8
  • 65
  • 104
2

This might work for you (GNU sed):

sed -e 'Rfile1' -e 'Rfile1' -e 'Rfile1' -e 'Rfile1' file2

or just use cat and paste:

cat file1 | paste -d\\n file2 - - - -
potong
  • 55,640
  • 6
  • 51
  • 83
1

another alternative with unix toolchain

$ paste file2 <(pr -4ats file1) | tr '\t' '\n'

50
line 1
line 2
line 3
line 4
43
line 5
line 6
line 7
line 8
21
line 9
line 10
karakfa
  • 66,216
  • 7
  • 41
  • 56
-1

Here's a goofy way to do it with paste and tr

paste file2 <(paste - - - - <file1) | tr '\t' '\n'

Assumes you don't have any actual tabs in your input files.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352