Text-Processing

用 s grep 最多 3 個空格

  • October 9, 2020

根據以下教程

  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:~$ 

你需要:

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   $

如果您想匹配 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
^^^^^^^^^^^^^^^^^^

在任何情況下,只要它們還包含不被空格包圍的 1 到 3 個空格的序列,它們仍然會返回包含 4 個或更多空格序列的行。

如果要排除包含 4 個或更多空格序列的行,那麼它將是:

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

或者,如果您仍然需要至少一個空格,或者換句話說,該行包含一個或多個空格字元序列,所有這些字元都至少有一個空格但不超過 3 個:

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

即返回除包含 4 個空格序列的行和僅由非空格組成的行之外的所有行。

或者再次使用 Perl 的環視運算符:

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

這與行的開頭匹配,前提是它後面跟著任意數量的字元和一個空格,並且後面沒有任何數量的字元和 4 個空格的序列。

儘管在同一個呼叫中可以同時進行正匹配和負匹配sed會更清晰:awk

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

引用自:https://unix.stackexchange.com/questions/613657