Bash脚本在awk中使用变量

时间:2016-05-26 19:21:28

标签: bash shell awk

我有一个变量LINE,并希望将它与awk一起使用,从table.txt中提取行编号为LINE的内容,并使其成为一个名为NAME的新变量,然后用于grep另一个文件。

NAME=`awk 'FNR==$LINE' < table.txt`
echo "this is $NAME"

似乎很接近,但不完全是语法。

如果我使用:

NAME=`awk 'FNR==1' < table.txt`
echo "this is $NAME"

然后echo给我table.txt的第一行,如果我使用2,我得到第2行,3第3行,然后我停止了变化。

感谢您的任何建议。 编辑第一篇格式化失礼。

2 个答案:

答案 0 :(得分:2)

您正在寻找:

NAME=`awk -v line="$LINE" 'FNR==line' < table.txt`

但是反引号符号已经过时,所以这更好:

NAME=$(awk -v line="$LINE" 'FNR==line' < table.txt)

并且你永远不应该使用全大写的变量名称,除非它们被导出(在shell中)以避免与内置名称冲突,所以它应该是:

name=$(awk -v line="$line" 'FNR==line' < table.txt)

但无论你做什么几乎肯定是错误的做法,应该完全在awk内完成。如果您正在考虑使用shell来操作文本,请确保完全理解why-is-using-a-shell-loop-to-process-text-considered-bad-practice中讨论的所有内容。

答案 1 :(得分:2)

补充Ed Morton's helpful awk-based answer

如果您只需要通过索引提取单行,sed允许更简洁的解决方案,也更容易优化(请注意,我已更改变量名称以避免all-uppercase variable names) :

name=$(sed -n "$line {p;q;}")
  • -n告诉sed默认情况下不打印(可能已修改)输入行
  • $line,假设此shell变量将其扩展为正整数(请参阅下面的警告),仅将输入行与该(基于1的)索引匹配。
  • {p;q;},打印(p)匹配行,然后立即退出整个脚本(q)作为优化(无需读取其余行)。

注意:

  • 对于更复杂的sed脚本,使用带有shell变量扩展的双引号shell字符串作为sed脚本并不是一个好主意,因为要理解由前面的贝壳与sed最终看到的结果会变得令人困惑。

  • 请注意,鉴于awk可以进行自己的正则表达式匹配(可能不需要awk),您可能最好单独使用grep解决问题。 )。