我有一个变量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,我得到第二行,3得到第三行,然后我停止了变化。
谢谢你的建议。编辑了第一篇文章的格式错误。
您正在寻找:
NAME=`awk -v line="$LINE" 'FNR==line' < table.txt`
但是backticks表示法已经过时了,所以这更好:
NAME=$(awk -v line="$LINE" 'FNR==line' < table.txt)
除非变量名被导出(在shell中)以避免与内置名称冲突,否则永远不应该对变量名使用所有大写字母,所以实际上应该是:
name=$(awk -v line="$line" 'FNR==line' < table.txt)
但无论你在做什么,几乎可以肯定都是错误的做法,应该完全在awk内完成。如果您正在考虑使用shell操作文本,请确保您完全理解"为什么使用shell操作-处理-文本考虑-错误-实践"中讨论的所有内容。
补充Ed Morton基于awk
的有用答案:
如果您只需要按索引提取一行,sed
可以提供一个更简洁的解决方案,也更容易优化(注意,我已经更改了变量名,以避免所有大写的变量名):
name=$(sed -n "$line {p;q;}")
-n
告诉sed
默认情况下不打印(可能修改)输入行$line
,假设这个shell变量将其扩展为正整数(请参阅下面的警告),只将输入行与该(基于1的)索引匹配{p;q;}
,打印(p
)匹配行,然后作为优化立即退出整个脚本(q
)(无需读取其余行)
注意:
对于更复杂的
sed
脚本,使用具有shell变量扩展的双引号shell字符串作为sed
脚本不是一个好主意,因为了解shell预先解释的内容与sed
最终看到的内容可能会令人困惑。注意Ed的观点,即考虑到
awk
可以进行自己的正则表达式匹配(可能不需要grep
),您可能最好单独使用awk
来解决问题。