0

I have a file.txt for example (it does not have the same number of columns for each row):

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

I have another file (file2.txt) that contains 2 columns

    a b
    c d
    e f

I use this command:

awk '{print $1,$(cut -f2 file2.txt)}' file.txt > final.txt

I want to take the second column of file2.txt and add it between columns 1 and 2 of file1.txt.

Ex. of results:

1 d 2 3 4 
5 d 5 6
7 f 7 7 7 9 10

I want also maintaining all the remaining columns of file1.txt

  • Should that be a "b" on the first line of your desired results? – glenn jackman Jul 4 at 14:38
  • Yes, sorry, it's a b – Will Jul 4 at 14:43
  • Then please edit your question to fix that typo. Also, does file2 really have leading whitespace? – glenn jackman Jul 4 at 14:44
1

Pure awk:

awk '
    FNR==NR{c[NR]=$2}
    FNR!=NR{$1 = $1 OFS c[FNR]; print}
' file2 file

Output:

1 b 2 3 4 
5 d 5 6 
7 f 7 7 7 9 10
  • 1
    You could also write FNR != NR {$1 = $1 OFS c[FNR]; print} but that forces awk to rebuild $0. I don't know which would be faster. – glenn jackman Jul 4 at 14:42
1

How about a little cut'n'paste?

paste -d" " <(cut -d" " -f1 file1.txt) <(cut -d" " -f2 file2.txt) <(cut -d" " -f2- file1.txt)
  • 1
    from OPs input, it must be -f6 for file2 ... – pLumo Jul 4 at 14:34
  • I don't understand your comment. "I have another file (file2.txt) that contains 2 columns" -- where does field 6 come from? – glenn jackman Jul 4 at 14:38
  • 1
    I copy-pasted the example file which has 4 spaces in front, and cut does not ignore those. So first 4 fields are empty. Not sure if it was by purpose or unintended, – pLumo Jul 4 at 14:39
  • 1
    Oh I see that. I was assuming there is no leading space and edited that out on my system. Can replace middle cut with <(awk '{print $2}' file2.txt) – glenn jackman Jul 4 at 14:40
0

While some implementations of awk do allow reading from piped sub-processes1, in this case I'd suggest reading the whole line from the second file, and doing the field splitting inside awk:

$ awk '(getline line < "file2.txt") > 0 {split(line,a); $1 = $1 FS a[2]} 1' file1.txt
1 b 2 3 4
5 d 5 6
7 f 7 7 7 9 10

Alternatively, you could consider using paste and cut, avoiding awk altogether


  1. see for example Using getline from a Pipe
0

With Perl, you read a line from file 1 then read a line from file2 via stdin. Afterwards stitch the lines in the desired order.

 $ perl -pale '$_ = join "\t", shift @F, <STDIN> =~ /\S\s+(\S+)/, @F' file1.txt < file2.txt

Output:

 1  b   2   3   4
 5  d   5   6
 7  f   7   7   7   9   10
0

Try with below command

awk 'FNR==NR{b[FNR]=$2;next}{print $1,b[FNR],$2,$3,$4,$5,$6,$7}' file2.txt  file1.txt 
  • 1
    The main problem here being that file.txt "does not have the same number of columns for each row" so hard-coding 7 fields is a limited solution. – Jeff Schaller Jul 9 at 11:05

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.