grep do 3 spacji z \ s

Oct 09 2020

Zgodnie z poniższymi samouczkami

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

\ s Dopasuj spację.

i

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

Niektóre wyrażenia regularne interwałowe to:

Opis wyrażenia

{n} Dopasowuje poprzedni znak występujący dokładnie „n” razy

{n, m} Dopasowuje poprzedni znak pojawiający się „n” razy, ale nie więcej niż m

{n,} Dopasowuje poprzedni znak tylko wtedy, gdy występuje „n” lub więcej razy

Przykładowy plik

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

Chcę po prostu grepować tylko do 3 spacji, minimum 1 spacja, maksimum 3 spacje Niestety, to naprawdę nie działa zgodnie z oczekiwaniami.

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

Pożądane wyjście

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

Odpowiedzi

8 αғsнιη Oct 09 2020 at 12:25

potrzebujesz:

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

\sdopasowuje biały znak, a nie tylko spację.
\Sdopasowuje znak niebędący białą spacją

w swojej próbie nie ograniczasz tego, że przed i po dopasowaniach nie powinny być spacje.


aby filtrować tylko przestrzeń i unikać używania PCRE, możesz:

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

lub do pracy na liniach mających na początku / końcu 1 ~ 3 spacje:

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

dane wejściowe ( cat -e infile):

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

wynik:

1 spaces$ 2 spaces$
3   spaces$ 3spaces$
3spaces   $
8 StéphaneChazelas Oct 09 2020 at 14:00

Jeśli chcesz dopasować sekwencję od 1 do 3 białych znaków, które nie są otoczone białymi znakami, możesz użyć operatorów rozglądania w Perlu:

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

Pasuje do:

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

Standardowo grepten sam efekt można osiągnąć stosując:

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

Tym razem dopasowujemy sekwencję od 1 do 3 białych znaków i znaki niebędące białymi znakami po obu stronach (lub początek ( ^) lub koniec ( $) tematu).

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

(z -o(rozszerzeniem GNU), okazuje się, że nie zgłasza, a bponieważ azostało już dopasowane wcześniej; podczas wyszukiwania więcej dopasowań zaczyna się od następnego znaku po ostatnim dopasowaniu).

Bez nich -Eotrzymujesz podstawowe wyrażenia regularne, które nie mają operatorów naprzemiennych (chociaż niektóre grepimplementacje obsługują \|to jako rozszerzenie), ale standardowo nadal możesz to zrobić:

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

Tym razem wyrażenie regularne dopasowuje całą linię, w tym od 1 do 3 spacji i opcjonalną ( \{0,1\}odpowiednik ERE ?) prowadzącą do niej część kończącą się niebiałą spacją i opcjonalną częścią następującą po niej, która zaczyna się od niebiałej spacji.

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

W każdym razie te nadal zwracałyby wiersze zawierające sekwencję 4 lub więcej białych znaków, o ile zawierają również sekwencję od 1 do 3 białych znaków nie otoczonych białymi znakami.

Gdyby chodziło o wykluczenie wierszy zawierających sekwencje 4 lub więcej białych znaków, byłoby to po prostu:

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

Lub jeśli nadal potrzebujesz co najmniej jednej białej spacji, lub innymi słowy, że linia zawiera jedną lub więcej sekwencji białych znaków, z których wszystkie mają co najmniej jedną białą spację, ale nie więcej niż 3:

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

Oznacza to, że zwraca wszystkie wiersze z wyjątkiem tych, które zawierają sekwencję 4 białych znaków i tych, które składają się wyłącznie z innych niż białe znaki.

Lub znowu z rozejrzeniem się Perla po operatorach:

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

To znaczy dopasuj początek wiersza, pod warunkiem, że następuje po nim dowolna liczba znaków i spacja oraz że nie ma po nim żadnej liczby znaków i sekwencji 4 białych znaków.

Chociaż byłoby to bardziej czytelne z sedlub awktam, gdzie można wykonać zarówno pozytywne, jak i negatywne dopasowanie w tym samym wywołaniu:

awk '/[[:space:]]/ && ! /[[:space:]]{4}/'
sed '/[[:space:]]/!d; /[[:space:]]\{4\}/d'
4 nezabudka Oct 09 2020 at 13:02

Możesz podejść z naprzeciwka. Wyklucz wiersze z więcej niż 3 spacjami w podciągu.

grep -Ev '\s{4,}'

-vOdwróć sens dopasowania, aby wybrać niepasujące wiersze.
Kotwice można wstawiać jako znaki inne niż białe znaki

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