bash sed - 在第一次出现 MATCH1 和下一次出现 MATCH2 之间提取字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4392106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
sed - extract STRING between first occurrence of MATCH1 and next occurrence of MATCH2
提问by lecodesportif
Using sed, I would like to extract STRING between the first occurrence of MATCH1and the next occurrence of MATCH2.
使用sed,我想在 的第一次出现MATCH1和下一次出现之间提取字符串MATCH2。
echo "abcd MATCH1 STRING MATCH2 efgh MATCH1 ijk MATCH2 MATCH2 lmnop MATCH1" | sed...
echo "abcd MATCH1 STRING MATCH2 efgh MATCH1 ijk MATCH2 MATCH2 lmnop MATCH1" | sed...
I tried this in various ways, but given that MATCH1and MATCH2both may appear several times in a row, it has turned out difficult to extract STRING. Any idea how I can achieve this result?
我想这以不同的方式,但考虑到MATCH1与MATCH2既有可能连续出现多次,它已经被证明难以提取STRING。知道如何实现这个结果吗?
采纳答案by Paused until further notice.
These only return the string between the matches and work even if MATCH1 == MATCH2.
这些只返回匹配项之间的字符串,即使MATCH1 == MATCH2.
echo ... | grep -Po '^.*?\K(?<=MATCH1).*?(?=MATCH2)'
Here's a sedsolution:
这是一个sed解决方案:
echo ... | sed 's/MATCH1/&\n/;s/.*\n//;s/MATCH2/\n&/;s/\n.*//'
The advantage of these compared to some of the other solutions is that each one consists of only one call to a single utility.
与其他一些解决方案相比,这些解决方案的优势在于每个解决方案只包含对单个实用程序的一次调用。
回答by Brent Newey
You can do it with perl using non-greedy regex matches:
您可以使用非贪婪的正则表达式匹配来使用 perl:
echo "abcd MATCH1 STRING MATCH2 efgh MATCH1 ijk MATCH2 MATCH2 lmnop MATCH1" | perl -pe 's|^.*?MATCH1(.*?)MATCH2.*$||'
seddoes not support these.
sed不支持这些。
EDIT: Here is a solution that combines Dennis' solution with sed:
编辑:这是将丹尼斯的解决方案与 sed 相结合的解决方案:
echo "abcd MATCH1 STRING MATCH2 efgh MATCH1 ijk MATCH2 MATCH2 lmnop MATCH1" | grep -Po '^.*?MATCH1.*?MATCH2' | sed 's/^.*MATCH1\(.*\)MATCH2$//'
回答by SiegeX
You can do this with two calls to sedby first replacing the white spaces with new lines then piping that output to another instance of sedwhich deletes everything else.
您可以通过两次调用来做到这一点,sed首先用新行替换空格,然后将输出管道传输到另一个实例,sed该实例删除其他所有内容。
sed 's/ /\n/g' | sed '1,/MATCH1/d;/MATCH2/,$d'
Edit
编辑
If the first line (after substitution) happens to be MATCH1, gnu sed can work around that by using 0,/MATCH1/instead of 1,/MATCH1/like so:
如果第一行(替换后)恰好是MATCH1,gnu sed 可以通过使用0,/MATCH1/而不是1,/MATCH1/像这样来解决这个问题:
sed 's/ /\n/g' | sed '0,/MATCH1/d;/MATCH2/,$d'
Edit2
编辑2
Optimized version of the single call to sedsolution that only needs 3 replacements instead of 4
单一调用sed解决方案的优化版本,只需要 3 个替换而不是 4 个
sed -r 's/MATCH1/&\n/;s/MATCH2/\n&/;s/^.*\n(.*)\n.*$//'
回答by potong
This might work for you:
这可能对你有用:
echo "abcd MATCH1 STRING MATCH2 efgh MATCH1 ijk MATCH2 MATCH2 lmnop MATCH1" |
sed 's/MATCH1/\n&/;s/[^\n]*\n//;s/\(MATCH2\).*//'
MATCH1 STRING MATCH2

