我使用sed在文本文件中找到某个匹配项,然后将此值放入变量中,我的问题是我只希望匹配后的文本,而不是整行。
Ans=$(sed -n '/^'$1':/,/~/{/:/{p;n};/~/q;p}' $file.txt)
文字档案
q1:answer1
~
q2:answer2
~
q3:answer3
~
实际输出
q1:answer1
预期产出
answer1
答案 0 :(得分:5)
使用grep:
Ans=$(grep -oP "^$1:\K.*" file)
如果您的grep
版本不支持-P
切换,请或使用perl:
Ans=$(var=$1 perl -lne '/^$ENV{var}:\K.*/ and print $&' file)
答案 1 :(得分:3)
如果需要sed
解决方案 - 例如,如果答案可以跨越多个行:
Ans=$(sed -r -n '/^'$1':(.*)/,/^(~)$/ { s//\1/; /^~$/q; p; }' file.txt)
(OSX用户:使用-E
代替-r
)。
\1
)将第一个匹配的行替换为其感兴趣的部分;第一个匹配的行和终止~
行之间的任何其他行不受替换的影响(假设它们也不以$1:
开头)并且还打印。q
替换为d
。相比之下,如果感兴趣的字符串仅限于以$1:
开头的行,则不需要也匹配~
行,并且命令可以是简化为:
Ans=$(sed -r -n '/^'$1':(.*)/ { s//\1/p; q; }' file.txt)
q;
。但是,使用grep
或awk
解决方案更容易处理单行案例 - 请参阅@ sputnick和@ anubhava的答案。如果您希望那些在第一次匹配后退出 - 如上面的代码段和OP中的代码那样 - 您需要向{{1}添加选项-m 1
解决方案和grep
到; exit
解决方案(awk
之前)。
答案 2 :(得分:2)
最好使用awk:
ans=$(awk -F':' -v s='q1' '$1 == s {print $2}' file)