Shell 在脚本中使用awk gensub的不同结果

Shell 在脚本中使用awk gensub的不同结果,shell,awk,Shell,Awk,在我尝试翻转由空格分隔的两部分组成的字符串时,我发现两种不同的结果取决于它的操作方式 方法1: echo "ABCD EFGH" | awk '{print gensub ( /( .+ ) ( .+ )/, "\\2 \\1", "g", $0 ) }' > ABCD EFGH #no flip (not desired resutls) 方法2: cat > temp.sh awk 'BEGIN {xx = "ABCD EFGH" xx_ = gen

在我尝试翻转由空格分隔的两部分组成的字符串时,我发现两种不同的结果取决于它的操作方式

方法1:

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

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

有什么好处?我需要在方法1中修复什么?谢谢你的帮助

你难道没有意识到在你的正则表达式匹配中有额外空格的第一个命令中有一个明显的输入错误吗

echo "ABCD EFGH" | awk '{print gensub ( /( .+ ) ( .+ )/, "\\2 \\1", "g", $0 ) }'
#                                         ^  ^   ^  ^ incorrect spaces defined
其定义如下。此外,您不需要将
$0
放在最后一个参数中,这是可以理解的,也是可以选择的,即如果没有明确提到
$0
,则默认情况下,该操作将采用整个
$0

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

你已经解释了为什么你的正则表达式不起作用。所以我只想指出,您是用GNU awk编写的,
gensub()
在大多数其他awk中都不存在

因此,为了便于移植,我建议您以不同的方式反转字段:

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

这将按相反顺序遍历字段,并将它们附加到变量中,由输出字段分隔符分隔。然后,它打印变量,并在执行时剥离。它还可以处理2个以上的字段。

Oops。你确实是对的。实际上,我的代码要长得多。空间是在我复制和粘贴以创建用作MWE的摘录时添加的。谢谢你指出这一点。由于我的实际任务与上面我天真的MWE有点不同,我正在发布另一个问题。通过使用substr,您的方法非常受欢迎。很不错的!非常感谢。