我有很多文件需要获取信息。
我的文件的示例:
第一个文件内容:
"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的有用答案。 - 此外,必须将比赛清理为单线(您最初不是作为要求)。
- 需要一次读取整个文件,如Maroun Maroun的有用答案。