grep 最多 3 个空格(带 \s)

grep 最多 3 个空格(带 \s)

根据以下教程

  1. https://linuxize.com/post/regular-expressions-in-grep/

\s 匹配一个空格。

  1. https://www.guru99.com/linux-regular-expressions.html

一些区间正则表达式是:

表达式说明

{n} 精确匹配前面出现“n”次的字符

{n,m} 匹配前面的字符出现 'n' 次但不超过 m

{n, } 仅当前面的字符出现“n”次或以上时才匹配该字符

样本文件

wolf@linux:~$ cat space.txt
0space
1 spaces
2  spaces
3   spaces
4    spaces
wolf@linux:~$ 

我只想 grep 最多 3 个空格,最小 1 个空格,最大 3 个空格不幸的是,它并没有真正按预期工作。

wolf@linux:~$ cat space.txt | grep -P '\s{1,3}'
1 spaces
2  spaces
3   spaces
4    spaces
wolf@linux:~$ 

wolf@linux:~$ cat space.txt | grep -P '\s{3}'
3   spaces
4    spaces
wolf@linux:~$ 

wolf@linux:~$ cat space.txt | grep -P '\s{3,3}'
3   spaces
4    spaces
wolf@linux:~$ 

wolf@linux:~$ cat space.txt | grep -P '\s{0,3}'
0space
1 spaces
2  spaces
3   spaces
4    spaces
wolf@linux:~$ 

所需输出

wolf@linux:~$ cat space.txt | grep -P '\s{0,3}' <- need to fix it here
1 spaces
2  spaces
3   spaces
wolf@linux:~$ 

答案1

你需要:

grep -P '\S\s{1,3}\S' infile

\s匹配空白字符,不仅空间。
\S匹配非空白字符

在您的尝试中,您并没有限制匹配项之前和之后不应该有空格。


要仅过滤空间并避免使用 PCRE,您可以执行以下操作:

grep '[^ ] \{1,3\}[^ ]' infile

或在具有前导/尾随 1~3 个空格的行上工作:

grep '\([^ ]\|^\) \{1,3\}\([^ ]\|$\)' infile

来自 https://regexper.com/

输入数据 (cat -e infile):

0space$
1 spaces$
2  spaces$
3   spaces$
4    spaces$
   3spaces$
    4space$
3spaces   $
4spaces    $

输出:

1 spaces$
2  spaces$
3   spaces$
   3spaces$
3spaces   $

答案2

如果您想要匹配 1 到 3 个不被空格包围的空格字符的序列,那么您可以使用 Perl 环视运算符:

grep -P '(?<!\s)\s{1,3}(?!\s)'

它匹配于:

         1
1234567890123456789
    a b  c   d    e
     ^ ^^ ^^^ 

使用 standard grep,您可以通过以下方式达到相同的效果:

grep -E '(^|[^[:space:]])[[:space:]]{1,3}([^[:space:]]|$)'

这次我们匹配 1 到 3 个空白字符以及两侧的非空白字符(或主题的开始 ( ^) 或结束 ( ))的序列。$

         1
1234567890123456789
   a b  c   d    e
^^^^ ^^^^

(使用-o(GNU 扩展),您会发现它不会报告之前已匹配的a b内容a;搜索更多匹配项时,它会从最后一个匹配项后的下一个字符开始)。

如果没有-E,您将获得没有交替运算符的基本正则表达式(尽管某些grep实现支持\|将其作为扩展),但标准情况下,您仍然可以这样做:

grep -x '\(.*[^[:space:]]\)\{0,1\}[[:space:]]\{1,3\}\([^[:space:]].*\)\{0,1\}'

这次,正则表达式匹配整行,包括 1 到 3 个空格和一个可选的(\{0,1\}相当于 ERE ?)前导部分,以非空格结尾,以及后面的一个以非空格开头的可选部分。

         1
1234567890123456789
   a b  c   d    e
^^^^^^^^^^^^^^^^^^

无论如何,这些仍然会返回包含 4 个或更多空格序列的行,只要它们还包含 1 到 3 个未被空格包围的空格序列。

如果要点是排除包含 4 个或更多空格序列的行,那么它就是:

grep -vE '[[:space:]]{4}'

或者,如果您仍然需要至少一个空格,或者换句话说,该行包含一个或多个空格字符序列,所有这些字符都至少有一个空格,但不超过 3 个:

grep -vE -e '[[:space:]]{4}' -e '^[^[:space:]]*$'

即返回除包含 4 个空格序列的行和仅由非空格组成的行之外的所有行。

或者再次使用 Perl 来查看运算符:

grep -P '^(?=.*\s)(?!.*\s{4})'

这与行的开头匹配,前提是其后跟任意数量的字符和空格,并且后面不跟任意数量的字符和 4 个空格的序列。

sed尽管使用orawk可以在同一调用中同时进行正向和负向匹配,但它会更清晰:

awk '/[[:space:]]/ && ! /[[:space:]]{4}/'
sed '/[[:space:]]/!d; /[[:space:]]\{4\}/d'

答案3

你可以从对面过来。排除子字符串中空格超过 3 个的行。

grep -Ev '\s{4,}'

-v反转匹配的意义,以选择不匹配的行。
您可以将锚点插入为非空白字符

grep -E '\S\s{1,3}\S'

答案4

$ grep -E '[[:space:]]' < file |
  grep -vE '[[:space:]]{4}'
1 spaces
2  spaces
3   spaces
  • 首先过滤所有包含至少 1 个空格字符的行。
  • 从这些中,过滤掉所有包含 4 个或更多空格字符的行。
  • 剩下的是由 1 到 3 个空格字符组成的行。

相关内容