Sed在两个字符串之间提取文本

时间:2013-05-20 05:45:25

标签: regex shell sed awk

请帮我使用sed。 我有一个如下文件。

START=A
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=B
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=C
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=D
  xxxxx
  xxxxx
END

我想在START = A,END之间获取文字。 我使用了以下查询。

sed '/^START=A/, / ^END/!d' input_file

这里的问题是, 我正在

START=A
  xxxxx
  xxxxx
END
START=D
  xxxxx
  xxxxx
END

而不是

START=A
  xxxxx
  xxxxx
END

Sed贪婪地发现。

请帮我解决这个问题。

提前致谢。

我可以使用AWK实现上述目标吗?

3 个答案:

答案 0 :(得分:24)

sed -n '/^START=A$/,/^END$/p' data

-n选项表示默认不打印;然后脚本说“在包含START=A的行和下一个END之间打印。

您也可以使用awk

执行此操作
  

模式可以由逗号分隔的两个模式组成;在这种情况下,执行动作          第一个模式出现的所有行,但第二个模式的出现。

(来自Mac OS X上的man awk)。

awk '/^START=A$/,/^END$/ { print }' data

在问题中给出数据文件的修改形式:

START=A
  xxx01
  xxx02
END
START=A
  xxx03
  xxx04
END
START=A
  xxx05
  xxx06
END
START=B
  xxx07
  xxx08
END
START=A
  xxx09
  xxx10
END
START=C
  xxx11
  xxx12
END
START=A
  xxx13
  xxx14
END
START=D
  xxx15
  xxx16
END

使用GNU sed或Mac OS X(BSD)sed以及使用GNU awk或BSD awk的输出是相同的:

START=A
  xxx01
  xxx02
END
START=A
  xxx03
  xxx04
END
START=A
  xxx05
  xxx06
END
START=A
  xxx09
  xxx10
END
START=A
  xxx13
  xxx14
END

请注意我是如何修改数据文件的,以便更容易看到打印的各种数据块来自文件。

如果你有不同的输出要求(例如'只有START = A和END'之间的第一个块,或'只有最后一个......'),那么你需要在问题中更清楚地表达出来。 / p>

答案 1 :(得分:3)

基本版......

sed -n '/START=A/,/END/p' yourfile

更强大的版本......

sed -n '/^ *START=A *$/,/^ *END *$/p' yourfile

答案 2 :(得分:2)

您的sed表达式在结尾前有一个空格,即/ ^END/。所以sed获得了起始模式,但没有得到结束模式并继续打印直到结束。使用sed '/^START=A/, /^END/!d' input_file(注意/^END/