选项-N
在pcregrep
中的含义是什么?
我无法理解本手册。
-N newline-type, --newline=newline-type
The PCRE library supports five different conventions for
indicating the ends of lines. They are the single-character
sequences CR (carriage return) and LF (linefeed), the two-
character sequence CRLF, an "anycrlf" convention, which rec‐
ognizes any of the preceding three types, and an "any" con‐
vention, in which any Unicode line ending sequence is
assumed to end a line. The Unicode sequences are the three
just mentioned, plus VT (vertical tab, U+000B), FF (form‐
feed, U+000C), NEL (next line, U+0085), LS (line separator,
U+2028), and PS (paragraph separator, U+2029).
When the PCRE library is built, a default line-ending
sequence is specified. This is normally the standard
sequence for the operating system. Unless otherwise speci‐
fied by this option, pcregrep uses the library's default.
The possible values for this option are CR, LF, CRLF, ANY‐
CRLF, or ANY. This makes it possible to use pcregrep on
files that have come from other environments without having
to modify their line endings. If the data that is being
scanned does not agree with the convention set by this
option, pcregrep may behave in strange ways.
我已经在Google和stackoverflow中进行了搜索,但我看不到任何示例。
如何使用此选项?请参阅下面的示例。 -N
只是不起作用。
$ cat /tmp/pcregrep-test
abcd
something1
something2
djfkhh
hh
$ pcregrep -Mo "abcd(.|\n)+k" /tmp/pcregrep-test
abcd
something1
something2
djfk
$ pcregrep -N ANY -Mo "abcd.+k" /tmp/pcregrep-test
$ pcregrep -N any -Mo "abcd.+k" /tmp/pcregrep-test
$ pcregrep --newline=ANY -Mo "abcd.+k" /tmp/pcregrep-test
$ pcregrep --newline=any -Mo "abcd.+k" /tmp/pcregrep-test
$
关键概念
\n
始终是.*
的分隔符,即.
永远不会包含\n
。-N
用于定义\n
是什么。 -N
指定的是.*
的分隔符。示例(Lorehead的原始版本)
$ echo -e "foo\012foo\015bar\012foo baz" > pcretest.txt
$ vim pcretest.txt
foo
foo^Mbar
foo baz
$ pcregrep -N LF -Mon "^foo.*$" pcretest.txt > result_LF
$ vim result_LF
1:foo
2:foo^Mbar
3:foo baz
# LF as the newline, the delimiter. Three matches.
$ pcregrep -N CR -Mon "^foo.*$" pcretest.txt > result_CR
$ vim result_CR
1:foo
foo
# CR as the newline, the delimiter. One match.
答案 0 :(得分:1)
您还可以在NEWLINES
标题下的documentation of PCRE中找到上述段落。该文档进一步解释了该标志如何影响正则表达式的解释:
在PCRE文档中,单词" newline"用于表示"表示换行符的字符或字符对"。 newline约定的选择会影响dot,circumflex和dollar元字符的处理,
/x
模式下#comments的处理,以及当CRLF是识别的行结束序列时,非匹配位置的推进 - 锚定模式。 [...]
解释文档中的每个项目:
在默认模式下,.
的定义排除"换行符"字符。确切的字符列表取决于此选项。
.
相当于[^\r]
。.
相当于[^\n]
。.
相当于(?:[^\r\n]|\r(?!\n)|(?<!\r)\n)
.
相当于[^\r\n]
.
等同于[^\r\n\v\f\x85\u2028\u2029]
,默认模式8位库除外,它等同于[^\r\n\v\f\x85]
(因为一个代码单元只有8-位为8位库。)样品运行:
$ echo -e 'abc\ndef\rlksdf\r\nsdf' | pcregrep -N CR -Mo 'abc.*'
abc
def
$ echo -e 'abc\ndef\rlksdf\r\nsdf' | pcregrep -N CRLF -Mo 'abc.*'
abc
lksdf
$ echo -e 'abc\ndef\rlksdf\r\nsdf' | pcregrep -N LF -Mo 'abc.*'
abc
(def
在第二轮中消失,因为它被\rlksdf
序列覆盖。)
在多行模式下,^
和$
是根据新行字符的定义定义的。在默认模式下,由于$
可以在终止换行符之前匹配,因此该设置也会影响$
可以匹配的内容。
如果您选择ANY-CRLF或ANY,其中包括CR,LR和CRLF,^
和$
将在CRLF序列之间不匹配。
这也是文档所指的内容当换行符号是一个识别的行结束序列时,新行约定的选择会影响[...]的处理,非锚定模式的匹配位置提升。给定^
多行模式和换行模式ANY-CRLF或ANY,它在CRLF之间不匹配,而是在CRLF中跳过LF之后。具有多线模式的^
被视为非锚定模式,因为它不会将匹配限制为字符串的开头(请参阅PCRE_INFO_FIRSTCHARACTERFLAGS
)。
在自由间距模式/x
中,我们可以编写以#
开头并以换行符结尾的单行注释。换行设置会影响评论的结束位置。
答案 1 :(得分:1)
修改:我在下面看到您的要求。该选项确实有效,我将原始帖子作为历史解释。
$ echo -e "foo\012foo\015bar\012foo baz" > pcretest.txt
$ more pcretest.txt
foo
bar
foo baz
$ pcregrep -N LF -Mo "^foo.*$" pcretest.txtfoo
foo
bar
foo baz
$ pcregrep -N CR -Mo "^foo.*$" pcretest.txt
foo
foo
$ pcregrep -N ANY -Mo "^foo.*$" pcretest.txt
foo
foo
foo baz
刚刚发生了什么:
ASCII字符10
或八进制\012
为LF
。 ASCII字符13
或八进制\015
为CR
。在Unix终端上,LF
表示开始一个新行,而CR
表示返回行的开头并覆盖之前的任何内容。
所以,我们写了foo LF foo CR bar LF foo baz
。当我们将这些原始代码回显到终端时,它将它们解释为:foo,new line,foo,擦除这一行并重新开始,bar,new line,foo baz。
当我们将LF
视为一行,CR
视为匹配.*
时,我们会得到三行foo
,foo CR bar
和foo baz
。所有这些都匹配模式,但当终端尝试显示第二行时,CR
告诉它用foo
覆盖bar
,所以它似乎在告诉我们{{ 1}}匹配模式bar
。但真的,在翻译中丢失了一些东西。
当我们将^foo.*$
视为行尾,并CR
作为匹配LF
时,我们有两行,.*
和foo LF foo
,其中第一个匹配模式。但是当Unix终端试图显示它时,它会在bar LF foo baz
处将该行分成两行。
当我们将LF
或CR
视为一行的结尾时,有四行,LF
,foo
,foo
和{{ 1}},其中第三个与模式不匹配。
为什么PCRE会这样做:
如果您正在阅读在Windows(或MS-DOS)上创建的文件,则此处的段之间的行可能以ASCII字符bar
(foo baz
)结尾。如果您正在读取在Unix上创建的文件,则行可能仅以CR LF
(10 13
)结尾。如果您正在阅读在旧Apple上创建的文件,则行可能以LF
(10
)结尾。 ISO决定通过引入自己的新方法来结束ISO-8859-1中没有人使用的线路,然后Unicode联盟做了同样的事情,从而决定帮助。
其历史原因在于,一些旧的手动电传打字机具有单独的命令以将纸卷推进一行(换行)并将打印头移回到行的开头(回车)。然后MIT和Apple都意识到,在计算机上,他们只需要一个。
PCRE希望能够理解任何这些格式。某些终端脚本实际上使用CR
将光标移动到当前行的最左侧位置,例如更新文本进度条,因此您可能希望搜索13
代码的那些。 / p>