管道到awk(Bash)

时间:2017-10-01 07:12:00

标签: awk

此代码有效:

#!bin/bash
ad="J Dt, K R, P MA
A F, E B, R VA
O T, O R, T OK
E A, P Rd, S MA
H S, B R, R MA"
byState() {
    a="$ad"
    h=$(echo "$a" | 
    sed -e 's/ MA/, Massachusetts/' | sed -e 's/ OK/, Oklahoma/' | sed -e 's/ VA/, Virginia/')
    h=$(echo "$h" | awk -F, '{print $4 ", " $0}' $* | sort)
    ... following code
    echo "$h"
}
byState

但是如果在功能byState中我将a="$ad"替换为a="$1",我会调用byState "$ad"我得到 awk: fatal: cannot open file 'J' for reading (No such file or directory)

有人可以解释这种不同的行为吗?

1 个答案:

答案 0 :(得分:2)

函数awk -F, '{script}' $*中的

byState()在wordsplitting和globbing之后获取函数的参数,并将它们用作awk的参数,awk处理参数(除了第一个时)用作脚本,以及任何形式的name = value(被视为赋值)作为要处理的文件名,从打开它们开始。由于第一个令牌是J,显然您在当前目录中没有名为J的文件,因此会出错。

如果您想使用byState()的第一个参数中的数据作为awk的输入,请执行

 echo "$1" | awk -F, '{script}' # with NO OTHER ARGS to awk

或更好

 printf '%s\n' "$1" | ...
 # which reliably won't mangle backslashes and some dashes 

甚至更好的支持它的贝壳(你没有识别你的)

awk -F, '{script}' <<<"$1"

此外,awk可以在没有任何sed的情况下进行字符串替换,但如果您想要sed,则可以在一个sed中进行多次替换。另外一些shell可以在没有sedawk的情况下自行进行字符串替换 - 但是你并没有问过这样做,只是你做错了。