grep do 3 spacji z \ s
Zgodnie z poniższymi samouczkami
- https://linuxize.com/post/regular-expressions-in-grep/
\ s Dopasuj spację.
i
- 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
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 $
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'
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'