简体   繁体   中英

How do i store the output of AWK as a variable to use in a SED command in a BASH script?

I have used this to create a character string:

awk -F "|" 'NR==1 {print $2$4}' file

I now want to use this string to replace another string using SED, using this code, which i know works:

sed -i.bak 's/\(<remote>\).*\(<\/remote>\)/<remote> http:\/\/blabla\/'$var' <\/remote>/g' file2.xml

But what i can't figure out is how to save the output of the awk as $var first to use as an input for SED. can anyone help? thanks.

Don't do that, just use awk, eg:

awk -F'|' '
NR==FNR { if (NR==1) var = $2$4; next }
{ gsub(/<remote>.*<\/remote>/,"<remote> http://blabla/" var " </remote>"); print }
' file file2.xml > tmp && mv tmp file2.xml

With GNU awk you could make it more efficient but it won't make a noticeable difference unless your first file is huge:

awk -F'|' '
NR==FNR { var = $2$4; nextfile }
{ gsub(/<remote>.*<\/remote>/,"<remote> http://blabla/" var " </remote>"); print }
' file file2.xml > tmp && mv tmp file2.xml

wrt a comment I made in someone else's post, here's why you should us -v var=val instead of populating variables in the awk args list unless you need to do that to change initial values between files (not necessary with GNU awk courtesy of BEGINFILE):

Here's a script to add the values stored in 3 files to some initial seed value and print the result for each file and across all files (the seed is just added once to the total). file2 is empty:

$ cat file1
3
6
$ cat file2
$ cat file3
2
5
$ cat tst.awk                                
BEGIN {
    print "seed value =", seed

    for (i=1; i<ARGC; i++)
        subtotal[ARGV[i]] = seed

    total = seed
}

{
    subtotal[FILENAME] += $0
    total += $0
}

END {
    for (filename in subtotal)
        print "File", filename, "subtotal =", subtotal[filename]

    print "total =", total
}
$ 
$ awk -v seed=7 -f tst.awk file1 file2 file3
seed value = 7
File file1 subtotal = 16
File file2 subtotal = 7
File file3 subtotal = 14
total = 23

All makes sense right? Now lets move the setting of "seed" into the argument list:

$ awk -f tst.awk seed=7 file1 file2 file3          
seed value = 
File file1 subtotal = 9
File file2 subtotal = 
File file3 subtotal = 7
File seed=7 subtotal = 
total = 16

Note that the seed value is missing from the first print, the subtotals and total are wrong, and there's an output trying to print a value for a file named "seed=7".

It's all explicable and predictable once you know exactly what you're doing with awk but I bet it's pretty baffling to a newcomer so IMHO populating variables in the arg list should not be how we advise people to initialize their variables by default since it's got far less intuitive semantics than -v variable=value .

var=$(awk -F "|" 'NR==1 {print $2$4}' file)

But its better you give us data and what to do with it. This way we can make an awk or sed that does it all.

Edit:

var="test"
echo "https://blabla/bla/bla </remote>" | awk '{$NF="</"v">"}1' v="$var"
https://blabla/bla/bla </test>

This will replace the something with value of $var

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