我想通过每行写入 1 个模式来提高脚本的可读性。
是否有一种语法可以让我转换grep 'foo\|bar\|barz'
为如下所示的内容?
grep 'foo\|
bar\|
barz'
答案1
模式参数实际上是模式列表,以换行符分隔。即使对于 也是如此grep -F
:您可以搜索多个字符串。所以你可以写:
grep 'foo
bar
barz'
但请注意,连续行不得缩进:任何前导空格都将成为模式的一部分。因此,您可能更愿意将模式列表作为单独的参数传递,并-e
在每个模式前面。然后,您可以\
在行尾使用 at 将 shell 命令在命令参数之间跨行分割grep
。两种语法是等效的。
grep -e 'foo' \
-e 'bar' \
-e 'barz'
grep
请注意,当传递-P
选项(对于 PCRE 正则表达式)时,这些都不适用于当前版本的 GNU ,在这些情况下会失败并显示grep: the -P option only supports a single pattern
.但是,您可以使用pcregrep
而不是 GNUgrep -P
并使用该x
标志来输入多行正则表达式:
pcregrep '(?x)
foo |
bar |
barz'
使用 时(?x)
,所有空白字符(包括 SPC 和 NL)都会被忽略,从而允许您根据需要缩进代码。
答案2
我认为没有必要|
。您可以使用-e
跨行的多个选项:
grep -e foo \
-e bar \
-e barz
答案3
使用 Raku(以前称为 Perl_6)
$ cat foo_bar_barz.txt | raku -ne '.grep(/
| foo
| bar
| barz
/).put;'
#输出:
1. foo
2. bar
3. barz
Perl6(现在的 Raku)项目的主要原因之一是重写正则表达式引擎,以便可以输入更多可读的代码。 Raku 默认设置包括在标记之间插入空格、在多行上编写正则表达式以及“修饰符”系统(现在称为“副词”)的修订版。 [作为后者的一个示例,您过去常常将“g”标记到正则表达式的末尾,现在“:g”出现在正则表达式的开头,这样您就知道要从 get 中匹配什么-去]。
以上是您发布的示例的 Raku 解决方案。请注意,在 Raku 中,|
交替运算符实现了最长令牌匹配 (LTM) 策略。此外,您还可以随意插入“前导”|
交替运算符来帮助您排列标记(见上文)。 Raku 认为这是正常的。
下面,为了让您了解幕后发生的情况,我使用m//
匹配运算符而不是分别捕获三个标记grep()
。捕获是通过括号完成的,编号从以下开始$0
:
$ cat foo_bar_barz.txt | raku -ne 'say m/
| (foo)
| (bar)
| (barz)
/;'
#输出:
「foo」
0 => 「foo」
「bar」
0 => 「bar」
「barz」
0 => 「barz」
Nil
请注意,输入文件如下(为了让我诚实,最后有一个假行):
$ cat foo_bar_barz.txt
1. foo
2. bar
3. barz
4. ziggy