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

Bash 如何在创建特定字符串后提取行,bash,awk,sed,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')”提取到“process.get('name6')”

我的示例文本是

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')”提取到“process.get('name6')”


如何使用sed提取行?

这应该可以工作并且。。。它根据OP请求使用sed:

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

这应该有效,而且。。。它根据OP请求使用sed:

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

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 "/process\.get\('name1'\)/,/process\.get\('name6'\)/" file
您可以在awk中转义元字符后使用regexp,就像在sed中被迫使用一样:

awk -v beg="process.get('name1')" -v end="process.get('name6')" \
        'index($0,beg),index($0,end)' file
awk "/process\.get\('name1'\)/,/process\.get\('name6'\)/" file
但是上面的第一个awk版本使用字符串而不是regexp和标志变量更简单(因为您不必找出哪些字符是/不是元字符),更健壮,将来更容易扩展

需要注意的是,sed不能对字符串进行操作,只能对regexp进行操作,因此当您说“我想搜索字符串”时,您应该停止尝试强制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用于单个行上的简单替换的详细信息,如需了解更有趣的内容,请使用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 "/process\.get\('name1'\)/,/process\.get\('name6'\)/" file
您可以在awk中转义元字符后使用regexp,就像在sed中被迫使用一样:

awk -v beg="process.get('name1')" -v end="process.get('name6')" \
        'index($0,beg),index($0,end)' file
awk "/process\.get\('name1'\)/,/process\.get\('name6'\)/" file
但是上面的第一个awk版本使用字符串而不是regexp和标志变量更简单(因为您不必找出哪些字符是/不是元字符),更健壮,将来更容易扩展

需要注意的是,sed不能对字符串进行操作,只能对regexp进行操作,因此当您说“我想搜索字符串”时,您应该停止尝试强制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

但我个人从未发现这一点有用,总有一些轻微的需求变化出现,让我希望我开始使用国旗。请参阅以了解有关该索引的详细信息,因为索引()对字符串而不是正则表达式进行操作,因此使用它时不需要转义RE元字符,因此对于OP显然只想搜索文本字符串的情况,它更简单、更健壮。我添加了更多的解释来帮助澄清。@Ed Morton这行吗<代码>awk'/name1/{f=1};f/name6/{f=0}'文件@user2138595否。除了我上面所说的OP只想使用字符串,而不是regexp之外,想象一下如果文件中存在
name123
names654
,您的示例会做什么。为什么
index
而不是
$0~
?因为index()对字符串而不是正则表达式进行操作,因此使用它时不需要转义RE元字符,因此对于OP显然只想搜索文本字符串的情况,它更简单、更健壮。我添加了更多的解释来帮助澄清。@Ed Morton这行吗<代码>awk'/name1/{f=1};f/name6/{f=0}文件@user2138595否。除了我上面所说的OP只想使用字符串,而不是regexp之外,想象一下如果文件中存在
name123
name654
,您的示例会做什么。