sed-从多行输入中仅获取替换的字符串,并省略不匹配的行!

问题描述 投票:18回答:4

我想要 sed忽略所有不匹配的行,仅输出替换的字符串(单行/多行)。

换句话说:我有干草堆,只希望返回针头,而不是所有被搜索到且保持不变的干草。

或再次换句话说:在多行字符串中搜索/替换RegEx描述的字符串,仅返回该字符串。 (因为可以使用PHP函数http://www.php.net/manual/en/function.preg-replace.php

我当前的解决方法首先使用grep进行过滤,然后仅将匹配的行通过管道传输到sed中进行替换:

echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | egrep "^Important1.*$" | sed -E "s/^Important1: *\b(.*)\b */\1/g"
# From the multiple line input I only want the "One One" (with pre/post whitespace removed, hence matching the word boundaries with "\b")
# And I want no "Bla bla" lines in the result!

但是我想使用sed中的单个解决方案。还是这超出了预期的sed用法,因此我应该更好地使用其他东西吗?顺便说一句,问题:multiline sed using backreferences似乎有某种联系,但我不确定!

regex sed replace multiline
4个回答
13
投票

编辑:以下内容已在Mac和Linux上进行了测试。

您可以像这样使用sed:

echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | \
   sed -n 's/^Important1: *\([^ ]*\) */\1/p'

OUTPUT:
one

说明

sed -n 's/^Important1: *\([^ ]*\) */\1/p'

-n # quiet / silent 

{
  s/^Important1: *\([^\ ]*\) */\1/ # replace "Important1: one " with 1st group i.e. "one"
  p                  # print the replaced text
}

6
投票

此sed命令完成了egrep和sed的结合:

echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla"
| sed -n -e "s/^Important1: *\b\(.*\)\b */\1/p"

您执行替换,并且替换后仅打印匹配的行。


4
投票
sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'

概念证明

$ echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'
One

0
投票

为了保持原始表达:

sed -E "s/^Important1: *\b(.*)\b */\1/g"

您可以对-n使用sed选项,并在p命令的末尾添加s标志,如下所示:

sed -En "s/^Important1: *\b(.*)\b */\1/gp"

证明:

echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | sed -En "s/^Important1: *\b(.*)\b */\1/gp"

s command使用以下格式:

sed OPTIONS... 's/regexp/replacement/flags'

-n--silent选项禁止自动打印图案空间1

p标志用于在替换后打印新的图案空间2

© www.soinside.com 2019 - 2024. All rights reserved.