join
will print each line of sorted input files that have the same first *(by default) field. So, setting the field delimiter (-t
) to ;
you get:
$ join -t\; A.txt B.txt
001;abc;def;ghi;jkl;pqr;mno
002;abc;def;ghi;jkl;pqr;mno
003;abc;def;ghi;jkl;pqr;mno
004;abc;def;ghi;jkl;pqr;mno
005;abc;def;ghi;jkl;pqr;mno
Combining that with awk
to switch the field positions around:
$ join -t\; A.txt B.txt |
awk -F';' -v OFS=';' '{k=$NF; $NF=$(NF-1); $(NF-1)=k; print;}'
001;abc;def;ghi;jkl;mno;pqr
002;abc;def;ghi;jkl;mno;pqr
003;abc;def;ghi;jkl;mno;pqr
004;abc;def;ghi;jkl;mno;pqr
005;abc;def;ghi;jkl;mno;pqr
With POSIX paste:
:|paste -d ' ||| ' fileA - - - - fileB
paste
will concatenate corresponding lines of all input files. Here we have six files, fileA
, four dummy files from standard in -
, and fileB
.
The list of delimiters include a space, three pipe and a space in that order will be used by paste
circularly.
For the first line of six files, fileA
will be concatenated with the first dummy file (which is nothing, thank to the no-op : operator), produce line1-fileA<space>
.
The first dummy file will be concatenated with the second by a pipe, produce line1-fileA |
, then the second dummy file with the third dummy file, produce line1-fileA ||
, the third dummy file with the the forth dummy file, produce line1-fileA |||
.
And the forth dummy file with fileB
, produce line1-fileA ||| line1-fileB
.
Those step will be repeated for all lines, give you the expected result.
The use of :|
is for less-typing, and mainly use in interactive shell. In a script, you should use:
</dev/null paste -d ' ||| ' fileA - - - - fileB
to prevent a subshell from being spawned.
Best Answer
Use
awk seen
if you don't want to sort the file: