简体   繁体   中英

How to print word get from variable in specific line with AWK?

I wish print in the "END" of the second line(or also in the end the file) a specific word get from a variable. it would be appreciated to have both methods.

I have a file my_file.txt with this content:

#Insert the names separeted by space     
l.lovre p.jhonson p.backer t.thompson q.ward

I tried to coding right so:

#!/bin/bash

filename=/path/my_file.txt

read -p "Insert name: " name

#my attempt
awk -v myvar="$name" 'END{print myvar}' $filename
 
echo 'Name added'

But doesn't work

I would get this result:

my_file.txt:

#Insert the names separeted by space     
l.lovre p.jhonson p.backer t.thompson q.ward **name**

Thanks in advance

sed is simpler:

sed -i "$ s/$/ $name/" my_file.txt

Edit: Make sure the last line in the file is not empty.

You could add it to the whole line at line 2 in the file with $0 = $0 FS myvar and keep your END block to print it after all the lines since you want that too. If you don't want it after all the lines, remove the END block.

awk -v myvar="$name" 'FNR==2 {$0 = $0 FS myvar}1; END{print myvar}' $filename

Output with name=Michele :

#Insert the names separeted by space
l.lovre p.jhonson p.backer t.thompson q.ward Michele
Michele

By default awk does not update the file. If you want to update the file you have a couple options:

######
# write to tmp file and then overwrite original file with tmp file

awk -v myvar="$name" 'END{print myvar}' "$filename" > tmpfile && mv tmpfile "$filename"

######
# if using 'GNU awk' you can use '-i inplace' to modify the file

awk -i inplace -v myvar="$name" 'END{print myvar}' "$filename"

As for the issue of appending the new name onto the end of the 2nd line, or creating a new line if there are no names in the current file: one idea:

######
# writing to tmp file

awk -v myvar="$name" 'FNR==2 { print $0,myvar; added=1; next} 1; END { if (added!=1) print myvar}' "$filename" > tmpfile
mv tmpfile "$filename"

######
# using 'GNU awk'

awk -i inplace -v myvar="$name" 'FNR==2 { print $0,myvar; added=1; next} 1; ENDFILE { if (added!=1) print myvar}' "$filename"

NOTES:

  • all input lines need to be echoed to stdout in order for them to 'remain' in the file, hence the standalone 1
  • END {} block processing takes place after a file has been processed; any output generated by the END {} block will go to stdout
  • if using GNU awk we have access to the ENDFILE {} block which is, in essence, the same as an END {} block except that processing in this case does apply to the file

Taking the GNU awk solution for a test drive:

$ filename=names.dat
$ cat "$filename"
# Insert the names separeted by space

$ name='b.bunny'
$ awk -i inplace -v myvar="$name" 'FNR==2 { print $0,myvar; added=1; next} 1; ENDFILE { if (added!=1) print myvar}' "$filename"
$ cat "$filename"
# Insert the names separeted by space
b.bunny

$ name='d.duck'
$ awk -i inplace -v myvar="$name" 'FNR==2 { print $0,myvar; added=1; next} 1; ENDFILE { if (added!=1) print myvar}' "$filename"
$ cat "$filename"
# Insert the names separeted by space
b.bunny d.duck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM