【问题标题】:Extract substring in Linux environemnt using Sed/awk/grep or any other tool使用 Sed/awk/grep 或任何其他工具在 Linux 环境中提取子字符串
【发布时间】:2018-02-12 04:13:28
【问题描述】:

我只想从特定字符串中获取子字符串。

例如,我有"sec(name=test)" 字符串。而且,我想使用 shell 提取 name=test 字符串。

我已尝试使用以下命令提取 "name=test" 值。但是,我得到的结果是sec()

echo "sec(name=test)"| grep -P '(sec\((.*)\))'

你能帮忙解决一下吗?

【问题讨论】:

  • 请不要要求教程。您应该针对特定的编程问题提出特定的问题。由于 Stack Overflow 向您隐藏了关闭原因:“要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。"
  • 目标是您添加一些自己的代码,以至少展示您为解决这个问题所做的研究工作。
  • @jww 我尝试使用以下命令进行提取。但是,我得到了像 sec() 这样的结果。但是,我想得到名称=测试。回声“秒(名称=测试)”| grep -P '(sec((.*)))'
  • 这应该可以grep -oP '\(\K[^)]+'

标签: regex linux awk sed grep


【解决方案1】:

您已经很接近了,但除非您想要 egrep(可能可用也可能不可用),否则带有基本正则表达式的 sed 可以,例如

$ echo "sec(name=test)"| sed 's/^[^(]*(\([^)]*\)).*$/\1/'
name=test

标准替换命令的详细信息是s/find/replace/,其中find 部分是收集反向引用 以在命令的replace 部分中使用的设置。例如,

find 部分

  1. ^ - 在字符串开头开始匹配的锚点
  2. [^(]* - 匹配[..class..] 中的所有字符,即"^("(不是左括号)
  3. ( - 消耗开头括号
  4. \(...\) 收集字符以保存为反向引用,这些字符是 "[^)]* 一切都不是结束括号,
  5. ) - 使用结束括号,
  6. .*$ - 该行的其余部分。

replace 部分

  1. \1 插入保存为第一个反向引用的字符(\(...\) 之间的内容,在您的情况下为 name=test

而且,你已经完成了......

【讨论】:

  • 非常感谢您的详细解释@David C.Rankin 它按预期工作。
【解决方案2】:

grep 将打印匹配的行,或与-o 匹配的字符串。捕获括号本身不会改变这一点。

grep -P 有一种方法可以说“匹配括号内的内容,但只有当以下环视也匹配时”所以你可以这样做

echo "sec(name=test)"| grep -oP '(?<=sec\().*?(?=\))'

lookbehind (?&lt;=sec\() 表示匹配必须紧跟在sec( 之前,而lookahead (?=\)) 同样要求匹配后跟)。我将匹配表达式从贪婪的.* 更改为吝啬的.*?,以避免它跨越一组括号。当然,这可能不是您想要的。您的问题没有揭示我们应该期望匹配的文本(特别是,它可以包含嵌套括号吗?)

不过,这很令人费解;更简单且可移植的解决方案是使用sed 将所需字符串前后的内容替换为空,然后打印。

echo "sec(name=test)"| sed -n 's/.*sec\(([^()]*)\).*/\1/p'

注意sed 使用的正则表达式方言比grep -P 支持的更简单,特别是不带引号的括号() 匹配字面意思,而反斜杠用于分组——与它们的工作方式相反Perl 和例如egrep.

【讨论】:

    【解决方案3】:

    有了Gnu-Sed,你也可以写

     echo "sec(name=test)"| sed -r 's/sec\(([^)]*)\)/\1/'
    

    使用 sed -r,您的圆括号在用于分组时不需要被屏蔽,但在字面意思时。有关详细信息,请参阅 ma​​n sed

    这会查找 sec(,然后查找任意数量的字符,这些字符不是右括号,然后是右括号。

    【讨论】:

    • -r 不可移植;一些方言使用-E 代替,而一些sed 实现根本不支持扩展正则表达式。
    • 你是对的。大多数 Linux 都带有 Gnu-sed,但当然不能保证。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 2013-03-01
    • 1970-01-01
    相关资源
    最近更新 更多