简体   繁体   中英

Different results using awk gensub in script

In my attempt to flip a character string with two parts separated by a space, I found two different results depending on how it's done.

Method 1 :

echo "ABCD EFGH" | awk '{print gensub ( /( .+ ) ( .+ )/, "\\2 \\1", "g", $0 ) 
}'
> ABCD EFGH #no flip (not desired resutls) 

Method 2 :

cat > temp.sh
awk 'BEGIN {xx = "ABCD EFGH"
            xx_ = gensub(/(.+) (.+)/, "\\2 \\1", "g", xx)
            print xx_
            }'
sh temp.sh
> EFGH ABCD  ## desired results 

What gives? What do I need to fix in method 1? Thanks for your help !

Don't you recognize an obvious typo in your first command of having extra spaces in your regex match?

echo "ABCD EFGH" | awk '{print gensub ( /( .+ ) ( .+ )/, "\\2 \\1", "g", $0 ) }'
#                                         ^  ^   ^  ^ incorrect spaces defined

It should have been defined as below. Also you don't need to put $0 in the last argument, as it is understood and optional to do, ie if $0 is not mentioned explicitly, the operation by default takes on the whole $0 .

echo "ABCD EFGH" | awk '{print gensub ( /(.+) (.+)/, "\\2 \\1", "g") }'

You've already got an explanation as to why your regex doesn't work. So I'll just point out that you're writing in GNU awk, and gensub() doesn't exist in most other awks.

So instead, for portability, I'll propose that you reverse your fields a different way:

$ echo "ABCD EFGH" | awk '{for(i=NF;i;i--) o=o OFS $i; print substr(o,length(OFS)+1)}'

This steps through your fields in reverse order and appends them to a variable, separated by your output field separator. It then prints the variable, stripping OFS as it goes. It also works with more than 2 fields.

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