grep bis zu 3 Leerzeichen mit \ s
Nach den folgenden Tutorials
- https://linuxize.com/post/regular-expressions-in-grep/
\ s Entspricht einem Leerzeichen.
und
- https://www.guru99.com/linux-regular-expressions.html
Einige reguläre Intervallausdrücke sind:
Ausdruck Beschreibung
{n} Entspricht dem vorhergehenden Zeichen, das n-mal genau erscheint
{n, m} Entspricht dem vorhergehenden Zeichen, das 'n' erscheint, jedoch nicht mehr als m
{n,} Entspricht dem vorhergehenden Zeichen nur, wenn es 'n' Mal oder öfter erscheint
Beispieldatei
wolf@linux:~$ cat space.txt 0space 1 spaces 2 spaces 3 spaces 4 spaces wolf@linux:~$
Ich möchte nur bis zu 3 Leerzeichen erfassen, mindestens 1 Leerzeichen, maximal 3 Leerzeichen. Leider funktioniert es nicht wirklich wie erwartet.
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:~$
Gewünschte Ausgabe
wolf@linux:~$ cat space.txt | grep -P '\s{0,3}' <- need to fix it here 1 spaces 2 spaces 3 spaces wolf@linux:~$
Antworten
du brauchst:
grep -P '\S\s{1,3}\S' infile
\sentspricht einem Leerzeichen, nicht nur einem Leerzeichen.
\SEntspricht einem Nicht-Leerzeichen
Bei Ihrem Versuch schränken Sie nicht ein, dass vor und nach Ihren Spielen kein Leerzeichen sein sollte.
Um nur nach Speicherplatz zu filtern und die Verwendung von PCRE zu vermeiden, haben Sie folgende Möglichkeiten:
grep '[^ ] \{1,3\}[^ ]' infile
oder um an Zeilen mit führenden / nachfolgenden 1 ~ 3 Leerzeichen zu arbeiten:
grep '\([^ ]\|^\) \{1,3\}\([^ ]\|$\)' infile
Eingabedaten ( cat -e infile):
0space$
1 spaces$ 2 spaces$
3 spaces$ 4 spaces$
3spaces$ 4space$
3spaces $ 4spaces $
Ausgabe:
1 spaces$ 2 spaces$
3 spaces$ 3spaces$
3spaces $
Wenn Sie mit einer Folge von 1 bis 3 Leerzeichen übereinstimmen möchten, die nicht von Leerzeichen umgeben sind, verwenden Sie hier Perl-Look-Around-Operatoren:
grep -P '(?<!\s)\s{1,3}(?!\s)'
Es passt zu:
1
1234567890123456789
a b c d e
^ ^^ ^^^
Mit Standard grepkönnen Sie den gleichen Effekt erzielen mit:
grep -E '(^|[^[:space:]])[[:space:]]{1,3}([^[:space:]]|$)'
Dieses Mal stimmen wir mit der Folge von 1 bis 3 Leerzeichen und dem Nicht-Leerzeichen auf beiden Seiten (oder dem Anfang ( ^) oder Ende ( $) des Betreffs) überein .
1
1234567890123456789
a b c d e
^^^^ ^^^^
(Mit -o(einer GNU-Erweiterung) wird festgestellt, dass es nicht so meldet, a bwie aes bereits zuvor gefunden wurde. Wenn Sie nach weiteren Übereinstimmungen suchen, beginnt es beim nächsten Zeichen nach der letzten Übereinstimmung.)
Ohne erhalten -ESie grundlegende reguläre Ausdrücke, die keine Wechseloperatoren haben (obwohl einige grepImplementierungen dies \|als Erweiterung unterstützen), aber normalerweise können Sie Folgendes tun:
grep -x '\(.*[^[:space:]]\)\{0,1\}[[:space:]]\{1,3\}\([^[:space:]].*\)\{0,1\}'
Dieses Mal stimmt der reguläre Ausdruck mit der gesamten Zeile überein, einschließlich der 1 bis 3 Leerzeichen und eines optionalen ( \{0,1\}das Äquivalent von ERE ?) führenden Teils, der in einem Nicht-Leerzeichen endet, und einem optionalen Teil, der darauf folgt und mit einem Nicht-Leerzeichen beginnt.
1
1234567890123456789
a b c d e
^^^^^^^^^^^^^^^^^^
In jedem Fall würden diese weiterhin Zeilen zurückgeben, die eine Folge von 4 oder mehr Leerzeichen enthalten, solange sie auch eine Folge von 1 bis 3 Leerzeichen enthalten, die nicht von Leerzeichen umgeben sind.
Wenn der Punkt darin bestehen würde, Zeilen auszuschließen, die Sequenzen von 4 oder mehr Leerzeichen enthalten, wäre dies nur:
grep -vE '[[:space:]]{4}'
Oder wenn Sie immer noch mindestens ein Leerzeichen benötigen oder mit anderen Worten, dass die Zeile eine oder mehrere Folgen von Leerzeichen enthält, die alle mindestens ein Leerzeichen, jedoch nicht mehr als 3 haben:
grep -vE -e '[[:space:]]{4}' -e '^[^[:space:]]*$'
Dies bedeutet, dass alle Zeilen zurückgegeben werden, mit Ausnahme derjenigen, die eine Folge von 4 Leerzeichen enthalten, und derjenigen, die ausschließlich aus Nicht-Leerzeichen bestehen.
Oder noch einmal mit Perls Blick um die Operatoren:
grep -P '^(?=.*\s)(?!.*\s{4})'
Dies entspricht dem Zeilenanfang, vorausgesetzt, es folgen eine beliebige Anzahl von Zeichen und ein Leerzeichen und keine Anzahl von Zeichen und eine Folge von 4 Leerzeichen.
Obwohl es besser lesbar wäre sedoder awkwo Sie sowohl eine positive als auch eine negative Übereinstimmung in derselben Aufforderung durchführen können:
awk '/[[:space:]]/ && ! /[[:space:]]{4}/'
sed '/[[:space:]]/!d; /[[:space:]]\{4\}/d'
Sie können vom Gegenteil kommen. Schließen Sie Zeilen mit mehr als 3 Leerzeichen in der Teilzeichenfolge aus.
grep -Ev '\s{4,}'
-vInvertieren Sie den Übereinstimmungssinn, um nicht übereinstimmende Linien auszuwählen.
Sie können Anker als Nicht-Leerzeichen einfügen
grep -E '\S\s{1,3}\S'