如何在与sed匹配后仅输出文本

时间:2014-02-15 18:50:10

标签: bash sed

我使用sed在文本文件中找到某个匹配项,然后将此值放入变量中,我的问题是我只希望匹配后的文本,而不是整行。

Ans=$(sed -n '/^'$1':/,/~/{/:/{p;n};/~/q;p}' $file.txt)

文字档案

q1:answer1
~
q2:answer2
~
q3:answer3
~

实际输出

q1:answer1

预期产出

answer1

3 个答案:

答案 0 :(得分:5)

使用

Ans=$(grep -oP "^$1:\K.*" file)
如果您的grep版本不支持-P切换,请

或使用

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;

但是,使用grepawk解决方案更容易处理单行案例 - 请参阅@ sputnick和@ anubhava的答案。如果您希望那些在第一次匹配后退出 - 如上面的代码段和OP中的代码那样 - 您需要向{{1}添加选项-m 1解决方案和grep; exit解决方案(awk之前)。

答案 2 :(得分:2)

最好使用awk:

ans=$(awk -F':' -v s='q1' '$1 == s {print $2}' file)