【问题标题】:Correct bash sed command syntax to get a correct substring正确的 bash sed 命令语法以获取正确的子字符串
【发布时间】:2020-03-18 13:29:59
【问题描述】:

试图从 a: 中获取子字符串

foo-bar-8568887b6f-d95wk 1/1 跑步 0 48m

得到一个: foo-bar-8568887b6f-d95wk

使用: sed 's/^.\((foo-bar)[^\s]+\).*$/\1/'

但是,这将返回整个字符串: foo-bar-8568887b6f-d95wk 1/1 Running 0 48m

在这种情况下,正确的 sed 命令是什么?

【问题讨论】:

  • [^\s] 匹配除\s 之外的任何字符,您需要[^[:space:]]*[^[:space:]]\{1,\}。此外,您的字符串不包含 ncc-full-druid-broker
  • 目标是获取foo-bar和第一个空格之间的子串。
  • 这里你可以使用awk '$0 ~ /^foo-bar/{print $1}'sed -n 's/^.*\(foo-bar[^[:space:]]*\).*$/\1/p'
  • 好的,这可以作为一个答案。
  • 为什么不只是awk '{print $1}'?如果你需要更多,那么edit你的问题可以提供一个更现实的例子。

标签: regex bash perl sed


【解决方案1】:

有几个问题:

  • .^ 之后需要一个字符
  • POSIX BRE 模式中的 (foo-bar)(foo-bar) 匹配,但您的字符串中没有括号
  • POSIX 括号表达式中的[^\s] 匹配除\s 之外的字符,而不是非空白字符
  • POSIX BRE 模式中的 + 匹配 + 字符。

使用

sed -n 's/^.*\(foo-bar[^[:space:]]*\).*/\1/p'

这里,

  • -n - 禁止默认行输出
  • s - 替换命令
  • /^.*\(foo-bar[^[:space:]]*\).*/- matches start of the string, any 0+ chars, capturesfoo-barand 0 or more chars other than whitespace into Group 1 (\1`),然后匹配字符串的其余部分
  • \1 - 将整场比赛替换为第 1 组的内容
  • p - 打印替换结果。

或者,考虑一个awk 命令,如果匹配总是出现在字符串的开头:

awk '$0 ~ /^foo-bar/{print $1}'

请参阅online demo。这意味着如果以foo-bar ($0 ~ /^foo-bar/) awk 开头的行将打印字段 1(默认字段分隔符是空格,因此您将获取从开头到第一个空格的子字符串)。

【讨论】:

  • 也很少 sed 将 \s 识别为 [[:space:]] 的简写(可能只是 GNU sed),如果他们这样做了,那么相反的将是 \S,而不是 [^\s]。顺便说一句,您不需要在 awk 命令中使用 $0 ~
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2020-12-03
  • 1970-01-01
  • 2011-01-05
  • 2021-01-12
  • 2020-10-12
  • 1970-01-01
相关资源
最近更新 更多