Nicolas Rosewick
Nicolas Rosewick

Reputation: 1998

Add strings contained in a text file to end of each 4th line

I've a file A.txt and a file B.txt. B.txt file contains a list of strings (one per line) that need to be put at the end of each 4th line in the A.txt file.

Example :

A.txt (I added the line number for this example - in real cases there is no such column) :

1   id_line1
2   some text
3   some text
4   some text
5   id_line2
6   some text
7   some text
8   some text
9   id_line3
10  some text
11  some text
12  some text
13  id_line4
14  some text
15  some text
16  some text

B.txt

1 A
2 B
3 C
4 D

So B.txt contains exactly 4 times less lines than A.txt lines (each B.txt line correspond to the 4th line in A.txt).

And at the end I would like a C.txt file as :

id_line1_A
some text
some text
some text
id_line2_B
some text
some text
some text
id_line3_C
some text
some text
some text
id_line4_D
some text
some text
some text

My issue is to loop through the B.txt file using sed/awk. Nevertheless I could also do it in more high-level languages (e.g. pyhton)

Any idea ? Thanks

Upvotes: 2

Views: 187

Answers (4)

eush77
eush77

Reputation: 4088

Here is a way to do it with sed, but also using paste, xargs and printf which are pretty standard:

sed 's:$:\n\n\n:' B.txt |
    paste -d'\n' A.txt - |
    xargs -n8 -d'\n' printf '%s_%s\n%s%s\n%s%s\n%s%s\n'

Roughly: (1) make the files the same length, (2) merge the lines one by one, (3) print in whatever format you want.

Upvotes: 2

potong
potong

Reputation: 58420

This might work for you (GNU sed):

sed '1~4R fileB' fileA | sed '1~5{N;s/\n/_/}'

Append a line of fileB to every fourth line of fileA and pipe the resulting file into a second invocation of sed which replaces the appended newline with an underscore.

Upvotes: 1

NeronLeVelu
NeronLeVelu

Reputation: 10039

awk 'FNR==NR{B[NR-1]=$0;next}{if(!((FNR+3)%4))$0=$0 B[(b++ %4)]}4' FileB.txt FileA.txt

with the comment inside

awk '
   # loading file B in memory, and read next line (until next file)
   FNR==NR { B[NR - 1]=$0;next}

   # complete file a
   {
   # 4th line (from 1st)
   # using the modulo of line numer (%) and a incremented counter (b)
   if( ! ( ( FNR + 3 ) % 4 ) ) $0 = $0 B[(b++ % 4)]
   # print every line
   print
   }

   # file order is mandatory
   ' FileB.txt FileA.txt

Upvotes: 0

Eric Duminil
Eric Duminil

Reputation: 54223

In Python3, this would do the trick:

with open('a.txt') as a_file:
    with open('b.txt') as b_file:
        for b_line in b_file:
            print(next(a_file).strip()+'_', end='')
            print(b_line, end='')
            for _ in range(3):
                print(next(a_file), end='')

With your examples, it outputs:

1   id_line1_1 A
2   some text
3   some text
4   some text
5   id_line2_2 B
6   some text
7   some text
8   some text
9   id_line3_3 C
10  some text
11  some text
12  some text
13  id_line4_4 D
14  some text
15  some text
16  some text

Upvotes: 0

Related Questions