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

发布于 2024-10-29 08:27:10 字数 961 浏览 1 评论 0原文

我希望 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 的预期用途,因此我应该更好地使用其他东西吗?顺便说一句,问题: 使用反向引用的多行 sed 似乎有某种相关性,但我不确定!

I want sed to omit all non-matching lines, and only output the replaced string (of the single/multiple intended line/s).

In other words: I've got a hay stack, and only want the needle returned, not all the hay which was searched and which remained unaltered.

Or again in other words: Search/replace a RegEx described string in a multi line string, and only get that string returned. (As it is possible with the PHP function http://www.php.net/manual/en/function.preg-replace.php )

My current workaround is to first filter with grep, and then pipe only the matching lines into sed for replacement:

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!

But I'd like to have a single solution within sed. Or is this out of intended sed usage, and should I therefore better use something else? Btw, issue: multiline sed using backreferences seemed somehow related, but I am not sure!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

野却迷人 2024-11-05 08:27:10

以下解决方案已在 Mac 和 Mac 上进行了测试Linux。

你可以像这样使用 sed:

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

输出:

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
}

Following solution has been tested on both Mac & Linux.

You can use sed like this:

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

OUTPUT:

one

Explanation

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
}
乖乖 2024-11-05 08:27:10
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
sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'

Proof of Concept

$ echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'
One
愁以何悠 2024-11-05 08:27:10

此 sed 命令执行的操作与 egrep 和 sed 的组合执行的操作相同:

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

执行替换并在替换后仅打印匹配的行。

This sed command does what your combination of egrep and sed does:

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

You perform the substitution and only print lines that matched, after the substitution.

听风念你 2024-11-05 08:27:10

为了保留原始表达式:

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

您可以使用 sed-n 选项,并将 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 命令 使用以下格式:

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

-n--silent 选项禁止自动打印模式空间 1

p 标志用于在进行替换时打印新的模式空间2

In order to keep your original expression:

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

you can use the -n option for sed and add the p flag to the end of your s command like this:

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

proof:

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

The s command uses the following format:

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

The -n or --silent option suppresses automatic printing of pattern space 1.

The p flag is used to print the new pattern space if a substitution was made2.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文