在两个带有多行的标签之间进行grep/sed



我有很多文件需要获取信息。

我的文件的示例:

第一个文件内容:

"test This info i need grep</singleline>"

第二个文件内容(有两行):

"test This info=
 i need grep too</singleline>"

在结果中我需要grep此文本:从第一个文件 - "我需要grep",从第二个文件中 - "此信息=我也需要grep"

在第一个文件中我使用:

grep -o 'test .*</singleline>' * | sed -e 's/test (.*)</singleline>/1/'

并成功获得"我需要GREP"的"此信息",但是我无法使用同一命令从第二个文件中获取信息。

请帮助重写命令或编写另一个。

或,如果您坚持使用grep,则可以:

grep -Pzo 'test(n|.)*(?=</singleline>)' test.txt 

要了解每个标志的含义,请使用grep --help

  • -P, - perl-regexp

    模式是Perl正则表达式

  • -o, - 唯一匹配

    仅显示匹配模式的一部分

  • -z,-null-data

    数据线以0字节结束,而不是newline

我会使用 pcregrep,可以匹配多行回调:

pcregrep -Mo 'test K((?s).)*?(?=</singleline>)' filename

技巧是:

  • -M允许pcregrep在多个线上匹配,
  • -o使其仅打印匹配,
  • K扔掉了比赛之前的比赛部分,
  • (?=</singleline>)是一个lookahead术语,如果(仅在)下面是 </singleline>,并且
  • ((?s).)*?要匹配任何非怪异的字符,也就是说,如果您在文件中有几次</singleline>出现,它将匹配到最接近而不是最较远的情况下。如果不需要,请删除?(?s)启用本术语本地的s选项,以使.在其中匹配Newlines;默认情况下它不会做到。

感谢@casimirethippolyte指出((?s).)替代(.|n)的替代方案。

看起来您正在解析引用的可打印编码文本,其中"软"线路断开(一个是固定线宽格格式的工件),用一条线表示 - 终止=(直接在n之前)。

由于在A 后来评论您也表示希望将每场比赛打印为一行,因此我建议以下2个通用评估:

  • 使用awk删除软件间断
  • 然后在结果上使用grep
awk '/=$/ { printf "%s", substr($0, 1, length($0)-2); next } 1' file |
  grep -Po 'test .*?(?=</singleline>)'

对Wintermute的帽子提示, *?和Wintermute's and Maroun Maroun的有益答案的有用答案,对正面的主张,(?=...)

不是 awk命令删除 =(以及newline);将substr调用替换为仅$0以保留它。

首先将感兴趣的字符串转换回他们的原始单线表示:

  • 比赛以其原始形式印刷。
  • 您可以将常规(GNU)grep与划分匹配使用;与此对比
    • 需要一次读取整个文件,如Maroun Maroun的有用答案。
      请注意,在撰写本文时,*必须用*?替换在他的答案中,以正确地工作在具有多个匹配的文件中工作。
    • 需要安装另一个实用程序pcregrep,如Wintermute的有用答案。
    • 此外,必须将比赛清理为单线(您最初不是作为要求)。

相关内容

  • 没有找到相关文章

最新更新