0

I'm trying to match two files and print the match result and leave empty line for unmatch result, based on the Number column 3. The idea here to make the two file length the same .

example: file 1

BMW 111  N1
BENZ 123 N2
TOYOTA 122 N3 

file2

N1
N23
N3 

result:

BMW 111 N1
*blank line (N23 does not exit in file 1*
TOYOTA 122 N3 

I used AWK to match the two file but I'm not able to insert blank line

awk 'NR==FNR{a[$1];next}$3 in a{print $1,$2,$3}' file2.txt file1.txt > result.txt 

as in https://stackoverflow.com/questions/977408/how-do-i-insert-a-blank-line-every-n-lines-using-awk

1
for line in $(cat file2); 
do
   grep $line file1 || echo ""; 
done

Produces the following output

$ for line in $(cat file2); do   grep $line file1 || echo ""; done
BMW 111  N1

TOYOTA 122 N3
$
  • Will not work as intended if matching data are on different lines. – DopeGhoti Jun 13 '18 at 19:45
  • @DopeGhoti Not true. The grep searches the entire file and picks the line that matches. – Timothy Pulliam Jun 13 '18 at 19:48
  • Actually, I did need to fix the logic however. && needed to be || – Timothy Pulliam Jun 13 '18 at 19:49
  • Try it again with N3 on the first line and N1 on the last line in one file; you will still see "matches". – DopeGhoti Jun 13 '18 at 19:49
  • But does not limit the matches to column 3. You can get false positives – glenn jackman Jun 13 '18 at 20:11
3

Instead of $3 in a{print $1,$2,$3}, try !($3 in a){$0 = ""} 1.

2

Assuming both files are sorted on the join field:

$ join -1 3 -a 2 -o1.1,1.3,1.3 file1 file2
BMW N1 N1

TOYOTA N3 N3

This does a relational JOIN operation on the two files, using the third column of file1 (with -1 3) and the first and only column of file2. We ask for all lines of file2 to be included in the output (with -a 2), even unpaired lines. For the output, we ask for all three fields of the first file to be printed (with the -o flag). Empty fields on unmatched lines will remain empty, but one could add -e something to fill them in with the string something.

If the two file are not sorted on the join field, you may pre-sort them using

sort -k3 -o file1 file1
sort -o file2 file2

or, you may do the sorting at the same time as the join, if your shell supports process substitutions, with

join -1 3 -a 2 -o1.1,1.3,1.3 \
    <( sort -k3 file1 ) \
    <( sort file2 )
1
  paste file1.txt file2.txt | sed -Ee 's/\s(\S+)\s+\1\s*$/ \1/;t'  -e g

This prints the contents of the files side by side per line basis and then we let Gnu sed operate on this line.

In case the last fields of files match, we erase that from the line and print it. Otherwise, we print an empty line, retrieved from the empty hold space.

Another way could be :

paste a.txt b.txt | awk '{NF -= $(NF) == $(NF-1) ? 1 : NF}1'

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.