我有一个变量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行,然后我停止了变化。
感谢您的任何建议。 编辑第一篇格式化失礼。
答案 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
解决问题。 )。