简单的 awk 包装函数或别名

简单的 awk 包装函数或别名

我见过有人使用 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}" "$@"
}

相关内容