我见过有人使用 bash 别名或基于 awk 的函数,我喜欢它的简单性,但不记得如何实现它(在 bash 中)。
假设您有一个大型格式化文件,您需要从中选择第 3、4、7 列。
为此你可以这样做:
cat bigfile.txt | awk '{print $3, $4, $7}' |less
我需要一个别名(或函数)pawk,我可以将其用作:
cat bigfile.txt | pawk 3,4,7 | less
以获得相同的效果。列数可以是任意的并且可以包括 NF。我尝试了一些方法来实现这一点,但无法弄清楚如何将任意数量的变量传递给 awk。
答案1
您可以使用这样的函数:
function pawk(){
awkString="{print "
for var in "$@"
do
awkString+=" \$$var"
done
awkString+=" }"
awk "$awkString"
}
例子:
cat bigfile.txt | pawk 3 4 7 | less
答案2
是的,那可能是一个函数,而不是别名。考虑到这一点,请尝试以下操作:
pawk(){
fields="$(sed -E 's/(^|,)/ \1\$/g'<<<"$1")"
shift
awk "{print $fields}" "$@"
}
然后你可以运行它:
pawk 3,4,7 bigfile.txt | less
或者
cat bigfile | pawk 3,4,7 | less
甚至
pawk 3,4,7 * | less
技巧是$
在每个逗号之前和函数第一个参数的开头添加 a (因此1,2,3
变为$1,$2,$3
),并将结果字符串保存在 shell 变量中。然后,您可以awk
在双引号中运行,以便$fields
扩展变量并将awk
其视为应该打印的字段。
应该sed -E
是相当可移植的,但是,herestring ( <<<"$1"
) 则不太如此。对于完全便携的版本,请使用:
pawk(){
fields="$(printf '$%s' $(echo 1,2,3 | sed 's/,/,\$/g'))"
shift
awk "{print $fields}" "$@"
}