【问题标题】:How to match nested text prefixed with spaces in sed or grep如何在 sed 或 grep 中匹配以空格为前缀的嵌套文本
【发布时间】:2019-02-23 22:01:34
【问题描述】:

我正在尝试使用 sed 或 grep 匹配嵌套文本,包括嵌套文本之前的行。

我正在使用的示例:

pattern3
    abcde
    fghij
pattern3
pattern1
    abcde
    fghij
pattern1
pattern1
    klmno
pattern1
pattern3
    abcde
pattern1
    pqrst
patterh3
    fghij

请注意,嵌套文本的前缀始终有四 (4) 个空格。此外,匹配模式后可能有也可能没有嵌套文本。

我对所有pattern1 行以及pattern1 后面以空格开头的行感兴趣。

我正在寻找的输出是:

pattern1
    abcde
    fghij
pattern1
pattern1
    klmno
pattern1
pattern1
    pqrst

我接近了:

sed -n '/^pattern1/,/^pattern1/p' data.txt

但它似乎在右侧 pattern1 匹配后跳过嵌套文本,并进入下一次迭代。

我也试过sed -n '/^\"pattern1\"$/,/^\"pattern1\"$/p' data.txt | sed '1d;$d',也没有运气。

【问题讨论】:

  • sed 用于执行s/old/new,这不是您正在执行的操作,而 grep 用于执行g/re/p,这不是您正在执行的操作。所以对How to match nested text prefixed with spaces in sed or grep 的直接回应是——你不需要,因为还有其他工具可以更好地完成这项工作。
  • @EdMorton 好点,当你以这种方式形成它时完全可以理解。谢谢!
  • 发布的答案都没有解决您的问题吗?如果他们没有,那么请提供关于仍然缺少的内容的反馈,但如果他们有,请查看stackoverflow.com/help/someone-answers 了解下一步该怎么做。

标签: bash parsing awk sed grep


【解决方案1】:

使用 GNU sed:

sed -n '/pattern1/{p;:x;n;s/^    .*/&/;p;tx}' file

或简化:

sed -n '/pattern1/{p;:x;n;p;/^    /bx}' file

输出:

模式1 abcde 福吉 模式1 模式1 克洛姆诺 模式1 模式1 pqrst

【讨论】:

  • 不错。但我仍然会使用 awk 解决方案。 :-)
【解决方案2】:

请您尝试关注一下。

awk '/pattern[23]/{flag=""} /pattern1/{flag=1} flag'  Input_file

awk '/pattern[^1]/{flag=""} /pattern1/{flag=1} flag'  Input_file

解释:在这里也添加解释。

awk '
/pattern[^1]/{        ##Checking condition if a line is having string pattern with apart from digit 1 in it then do following.
  flag=""             ##Nullifying variable flag value here.
}
/pattern1/{           ##Checking condition here if a line is having string pattern1 then do following.
  flag=1              ##Setting value of variable flag as 1 here.
}
flag                  ##Checking condition if value of flag is NOT NULL then print the line value.
' Input_file          ##Mentioning Input_file name here.

【讨论】:

  • 这很好,我很欣赏你的解释。它比我的版本好得多:awk '/.*/ { doReset=1 } /^pattern1/ { doReset=0; active=1; print } /^ .*/ { doReset=0; if (active) print } /.*/ { if (doReset) active=0 }' data.txt。如果我无法获得sed 解决方案,我会将此视为备用。 :)
  • 看起来像这样的作品 - 如果在pattern1 的最后一个实例之后有任何不匹配的行,那么它将它们留在后面。
  • @CzarMatt,请在这里给我例子,然后我会编辑代码。
  • 我已经更新了问题中的示例以反映。谢谢你。 :)
【解决方案3】:
$ awk '/^[^ ]/{f=/^pattern1$/} f' file
pattern1
    abcde
    fghij
pattern1
pattern1
    klmno
pattern1
pattern1
    pqrst

【讨论】:

    【解决方案4】:

    这可能对你有用(GNU sed):

    sed '/^\S/h;G;/pattern1/P;d' file
    

    将当前模式存储在保持空间中并将其附加到每一行。如果当前模式是 pattern1,则打印当前行和/或删除当前行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 2012-10-24
      • 1970-01-01
      • 2022-01-07
      相关资源
      最近更新 更多