根据以下教程
\s 匹配一个空格。
和
一些区间正则表达式是:
表达式说明
{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
输入数据 (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 个空格字符组成的行。