如何在创建特定字符串后提取行

时间:2016-01-19 14:11:42

标签: bash awk sed

我的示例文字是,

AA BB  CC
DDD
process.get('name1')
process.get('name2')
process.get('name3')
process.get('name4')
process.get('name5')
process.get('name6')
EEE
FFF
...

我想首先搜索字符串“ process.get('name1')”,如果找到,则从“ process.get('name1')“to” process.get('name6')“。

如何使用sed提取线条?

2 个答案:

答案 0 :(得分:3)

这应该有效......并且它根据OP请求使用sed:

$ sed -n "/^process\.get('name1')$/,/^process\.get('name6')$/p" file

答案 1 :(得分:2)

sed用于单独行的简单替换,对于你应该使用awk更有趣的事情:

$ awk -v beg="process.get('name1')" -v end="process.get('name6')" \
    'index($0,beg){f=1} f; index($0,end){f=0}' file
process.get('name1')
process.get('name2')
process.get('name3')
process.get('name4')
process.get('name5')
process.get('name6')

请注意,你可以在awk中使用一个范围,就像你被迫在sed中一样:

awk -v beg="process.get('name1')" -v end="process.get('name6')" \
        'index($0,beg),index($0,end)' file

你可以在awk中转义metachars后使用regexp,就像你被迫在sed中一样:

awk "/process\.get\('name1'\)/,/process\.get\('name6'\)/" file

但上面的第一个awk版本使用字符串而不是regexps和一个标志变量更简单(因为你不必弄清楚哪些字符是/不是RE元字符),更健壮,更容易扩展将来。

重要的是要注意sed不能对字符串进行操作,只需要正则表达式,所以当你说“我想搜索一个字符串”时,你应该停止尝试强制sed表现得好像它可以做到这一点。

想象一下,您的搜索字符串会作为位置参数$1$2传递给脚本。使用awk,你只需要以预期的方式从它们中启动awk变量:

awk -v beg="$1" -v end="$2" 'index($0,beg){f=1} f; index($0,end){f=0}' file

而对于sed,你必须做类似的事情:

beg=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< "$1")
end=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< "$2")
sed -n "/^${beg}$/,/^${end}$/p" file

停用存在的任何元字符。有关为sed转义RE metachars的详细信息,请参阅Is it possible to escape regex metacharacters reliably with sed

最后 - 如上所述,您可以在awk中使用带字符串的范围表达式:

awk -v beg="$1" -v end="$2" 'index($0,beg),index($0,end)' file

但我个人从来没有发现有用,总会有一些轻微的要求变化让我希望我开始使用旗帜。有关详细信息,请参阅Is a /start/,/end/ range expression ever useful in awk?