3
cat file1
xi=zaoshui jiao=@E0488_5@
chi=fan da qiu=@E0488_3@
gong=zuo you xi @E0977_5@

cat file2
@E0488_3@ @E21562_3@
@E0488_5@ @E21562_5@
@E0977_3@ @E21630_3@
@E0977_5@ @E21630_5@
@E0977_6@ @E21631_1@

Purpose: if $NF in file1 found in file2 $1, than replace $NF in file1 with file2 $2.otherwise, makes no change.

My Code:

awk 'NR==FNR{a[$1]=$2;next}
     {split($NF,a,"=");for($NF in a){$NF=a[$NF]}}1' test2.txt test1.txt

But it comes error:

awk: cmd. line:1: NR==FNR{a[$1]=$2;next}{split($NF,a,"=");for($NF in a){$NF=a[$NF]}}1
awk: cmd. line:1:                                                     ^ syntax error

Does my code look right? It seems grammar issue happens. How can I improve it?

My expect output:

   xi=zaoshui jiao=@E21562_5@
   chi=fan da qiu=@E21562_3@
   gong=zuo you xi @E21630_5@
3
  • You can't use $NF as the loop variable. I guess you want for (x in a){$x=a[x]} but it's not really clear. Voting to close as typo. Commented Dec 13, 2017 at 5:24
  • thank you . sorry for the inconvenience , I have update my question Commented Dec 13, 2017 at 5:34
  • @Sundeepyou are right, I change if instead of for,but the output makes no change compared with the original file1, why ? ` awk 'NR==FNR{a[$1]=$2;next}{split($NF,a,"=");if($NF in a){$NF=a[$NF]}}1'` Commented Dec 13, 2017 at 6:10

3 Answers 3

2
  • for($NF in a) is not valid syntax, ($NF gives value)

it can be like

for (var in array)
    body

Read More from : GNU AWK Scanning-an-Array

  • Used sub($NF,a[$NF]) to retain your original field separator, since last record, last field has space before, whereas other lines last field has = before, assuming values doesn't repeat other than last field.

Test Results:

$ cat file1
xi=zaoshui jiao=@E0488_5@
chi=fan da qiu=@E0488_3@
gong=zuo you xi @E0977_5@

$ cat file2
@E0488_3@ @E21562_3@
@E0488_5@ @E21562_5@
@E0977_3@ @E21630_3@
@E0977_5@ @E21630_5@
@E0977_6@ @E21631_1@

$ awk 'FNR==NR{a[$1]=$NF;next}($NF in a){sub($NF,a[$NF])}1' file2 FS='[ =]' file1
xi=zaoshui jiao=@E21562_5@
chi=fan da qiu=@E21562_3@
gong=zuo you xi @E21630_5@
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, it is really great. but one more question, when I changed the FS='[ =]' with FS='=' in your code , the output changed as not I expect. So, could you please make it more clear about separator for FS='[ =]' ?
@huangcheng with FS='[ =]' you are telling awk that, field separator being either space or =, I made it because of your last line, otherwise awk will treat last field for last record ($NF => zuo you xi @E21630_5@), if you just set FS='='
2

Not sure completely but could you please try following and do let me know if this helps you.

awk 'FNR==NR{a[$1]=$NF;next} ($NF in a){$NF=a[$NF]} 1' FS="=" file2 FS='[= ]' OFS="=" file1

Output will be as follows.

xi=zaoshui jiao=@E0488_5@
chi=fan da qiu=@E0488_3@
gong=zuo you xi @E0977_5@

EDIT: Adding explanation too now for same.

awk '
FNR==NR{                               ##Checking condition FNR==NR which will be TRUE when first Input_file named file2 is being read.
  a[$1]=$NF;                           ##making an array named a whose index is $1 of current line and value is last field of the current line.
  next                                 ##next will skip all the further statements now.
}
($NF in a){                            ##Checking condition here if last field of current line of Input_file file1 is present in array a if yes then do following.
  $NF=a[$NF]                           ##creating last field value to array a value whose index is $NF of current line in Input_file file1.
}
1                                      ##1 will print the lines for Input_file file1.
' FS="=" file2 FS='[= ]' OFS="=" file1 ##Setting FS="=" for file2 and setting FS value to either = or space for file1 and setting OFS value to = for file1 too.

6 Comments

yes. it seems makes no change, I have update my question
@huangcheng, have changed my code accordingly now, let me know if that helps you.
yes ,it works, could you please make it clear for separator FS='[= ]' mean?
@huangcheng, added explanation now for my code please have a look to it and let me know if this helps you.,
really appreciate for your explanation~
|
2

My code is as below, hope it could be helpful even if it's not the most efficient answer.

awk '$NF ~ /=/ {gsub("="," @ ",$NF)}{print $0}' file1 > file3
cat file3
xi=zaoshui jiao @ @E0488_5@
chi=fan da qiu @ @E0488_3@
gong=zuo you xi @E0977_5@

As you said ,replace file1 with file3, if $NF of file3 found in file2 $1, than replace $NF of file3 with file2 $2

awk 'NR==FNR {a[$1]=$2;next}($NF in a){$NF=a[$NF]}1' file2 file3 | sed 's/ @ /=/g'
xi=zaoshui jiao=@E21562_5@
chi=fan da qiu=@E21562_3@
gong=zuo you xi @E21630_5@

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.