gawk: Merge N files into one

hi all!

i'm an awk newbie and have been trying in vain to merge N files together.

ie.

file1.txt:

a b c
1 1 1
2 2 2
3 3 3
4 4 4

file2.txt:

a b c
5 5 5
6 6 6
7 7 7
8 8 8

file3.txt:

a b c
9 9 9
10 10 10

i want to end up with:

a b c
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
10 10 10

And i also like to check if the 2nd or 3rd file has diferente number of colums, it stops.

Thanks in advance.

BR.

awk 'NR==1{print;next}FNR==1{next}1' file1.txt file2.txt file3.txt > outfile
1 Like

Thanks

But can I validate that the number of columns of each file is the same?

Yes, awk stores the number of the columns in the internal variable NF.

For example:

awk '{print FILENAME, NF}' file1.txt file2.txt file3.txt

can send me please the code integrated that before processing all files validate the headers - number of columns is equal in all.

Only creates or process the new merged file if the number of columns is equal in boths files.

This prints the filename and the number of columns if it has more or less columns then the first row:

awk 'NR==1{n=NF}NF != n{print FILENAME " has " NF " columns"} 'file1.txt file2.txt file3.txt

I believe that I did not explained well.

What I want is the following:

file1.txt:

a b c
1 1 1
2 2 2
3 3 3
4 4 4

file2.txt:

a b c
5 5 5
6 6 6
7 7 7
8 8 8

file3.txt:

a b c
9 9 9
10 10 10

i want to end up with:

a b c
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
10 10 10

but if the 3rd file was:

a b
9 9
10 10 

the tool should not generate any files.

And can you explain what represent 1 in the code: {next}1'. I tried 2,3,etc numbers and it works.

Thanks for your time but I am a zero in gawk

An awk statement has the form:

condition {action}

Conditions in awk control the execution of actions and actions are executed when the condition is true (1, 2, 3 or any value other then 0 or "" ).
If the condition is true and there are no actions between braces, awk prints the current record by default.

Try this:

awk 'NR==1{
  print;nf=NF;next
}
FNR==1{next}
nf!=NF{
  system("rm -f outfile"); exit
}1' file1.txt file2.txt file3.txt > outfile

Thanks in advance.

If the files have the same number of columns it works fine.
But if any file does not have the same number of columns gives error

i have error:
'0 Is not recognized as an internal or external command, operable program or batch file.

I don't get any error.... try nawk instead of awk.

I'm working on windows so i change:

NR==1{
  print;nf=NF;next
}
FNR==1{next}
nf!=NF{
  system("del -f outfile"); exit
}1

and error is:

The process can not access the file because it is being used by othe
the process.

I don't use awk in windows... but you can use the code of post #4 to check the columns of the files and the code of post #2 to merge the file.

I've used gawk on Windows before, but I don't have it available now to play with. You could try using redirection within the script so you may close the file before trying to delete it, and/or storing the output in memory before dumping it into an output file. This shows the latter:

[mute@geek ~/temp/sameeribraimo]$ cat merge.awk
BEGIN {
        outfile=ARGV[--ARGC]
        print "output: " outfile
}
NR==1{nf=NF;a[r++]=$0}
NF!=nf{exit 1}
FNR!=1{a[r++]=$0}
END {for (i=0;i<r;i++) print a > outfile}
[mute@geek ~/temp/sameeribraimo]$ gawk -f merge.awk file?.txt output.txt
output: output.txt
[mute@geek ~/temp/sameeribraimo]$ cat output.txt
a b c
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
10 10 10

moving to Windows forum