nach Sonderzeichen. Ich möchte nach Zeilen suchen, die eines der folgenden Zeichen enthalten:
:
/
/
?
#
[
]
@
!
$
&
"
(
)
*
+
,
;
=
%
Antwort
grep "[]:/?#@\!\$&"()*+,;=%[]"
Innerhalb eines Ausdrucks in Klammern, [...]
, sind nur sehr wenige Zeichen “ special “ (nur eine sehr kleine Teilmenge wie ]
, -
und ^
und die drei Kombinationen [=
, [:
und [.
). Wenn Sie ]
in [...]
aufnehmen, muss die ]
an erster Stelle stehen (möglicherweise nach einem ^
). Ich habe mich dafür entschieden, die ]
zuerst und die [
zuletzt für die Symmetrie zu setzen.
Das einzige andere, an das ich mich erinnern muss, ist Da eine Zeichenfolge in einfachen Anführungszeichen kein einfaches Anführungszeichen enthalten darf, verwenden wir doppelte Anführungszeichen um den Ausdruck. Da wir eine Zeichenfolge in doppelten Anführungszeichen verwenden, wird die Shell darin herumstochern, damit die Dinge erweitert werden können. Aus diesem Grund wird die $
als \$
ausgeblendet, wodurch die Shell ein Literal $
bis grep
, und wir entkommen !
als \!
, da es „eine Geschichte ist Erweiterung in bash
(allerdings nur in interaktiven bash
-Shells).
Möchten Sie einen Backslash in die Wenn Sie dies festlegen, müssen Sie es als \\
maskieren, damit die Shell grep
einen einzelnen Backslash gibt. Auch wenn Sie einschließen möchten Wenn Sie ein Backtick `
ausführen, muss es ebenfalls als \`
maskiert werden, da sonst eine Befehlssubstitution gestartet wird.
Der Befehl oben würde jede Zeile extrahieren, die mindestens eines der Zeichen im Ausdruck in Klammern enthält.
Verwenden einer Zeichenfolge in einfacher Anführungszeichen anstelle einer Zeichenfolge in doppelten Anführungszeichen, wodurch die meisten Belästigungen umgangen werden Welche Zeichen die Shell interpretiert:
grep "[]:/?#@!$&"""""()*+,;=%[]"
Hier ist das einzige, woran Sie sich erinnern sollten, abgesehen von der Platzierung der ]
ist, dass eine Zeichenfolge in einfachen Anführungszeichen kein einfaches Anführungszeichen enthalten kann. Stattdessen verwenden wir eine Verkettung von drei Zeichenfolgen:
-
"[]:/?#@!$&"
-
"""
-
"()*+,;=%[]"
Ein anderer Ansatz wäre die Verwendung der POSIX-Zeichenklasse [[:punct:]]
. Dies entspricht einem einzelnen Zeichen aus der Menge !"#$%&"()*+,-./:;<=>?@[\]^_`{|}~
, die eine größere Menge ist als die in der Frage angegebenen „(es enthält zusätzlich ), aber alle “ Satzzeichen „, die POSIX definiert.
LC_ALL=C grep "[[:punct:]]"
Kommentare
- @ilkkachu ‚ hat die
$
drin! Danke! - Wenn ich versuche, den Befehl auszuführen, erhalte ich den Fehler
bash: !\: event not found
. - @ user9371654 Darn
bash
! 🙂 Entkomme auch der!
… Keinebash
Benutzer, den ich vergessen habe. Ich werde aktualisieren … -
"[\!]"
wird auf[\!]
erweitert Selbst wenn die Verlaufserweiterung aktiviert ist, stimmt dies mit dem Backslash überein. ‚ benötigen einfache Anführungszeichen oder verwenden\!
outsi de von Anführungszeichen. - Beachten Sie, dass ‚ nicht nur
bash
,zsh
hat auch diese nervige Funktion, die von csh geerbt wurde. in csh!
speziell auch in'...'
und auch wenn nicht interaktiv. Incsh
(im Gegensatz zu bash oder zsh) würde die Verwendung von"\!"
hier jedoch funktionieren (der Backslash wird entfernt).
Antwort
Sie können die Zeichenklasse [:punct:]
verwenden, wenn Sie dies tun Es macht nichts aus, dass es auch mit anderen Satzzeichen und Sonderzeichen übereinstimmt:
grep "[[:punct:]]" file
Kommentare
- Die
punct
Zeichenklasse (kein Makro) entspricht!"#$%&'()*+,-./:;<=>?@[\]^_
{|} ~ `im C-Gebietsschema, bei dem es sich um einen geringfügig größeren Zeichensatz handelt als Was der Benutzer hat, aber es kann gut genug sein.
Antwort
Sie können den vollständigen regulären Ausdruck verwenden, um zu finden Sonderzeichen in eckigen Klammern, wenn Sie nach einem Sonderzeichen suchen. Eine großartige Ressource zum Üben, Lernen und Überprüfen Ihres regulären Ausdrucks ist regex101.com .
Hierbei werden reguläre Perl-Ausdrücke verwendet, die mit GNU grep mit der Option -P
verwendet werden können:
grep -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])" ^^^
Beachten Sie, dass Sie zwei Backsl benötigen Asche vor dem Dollarzeichen, da es in der Shell eine besondere Bedeutung hat und der erste Backslash für die Shell entgeht. (Mit nur einem Backslash vorne würde die Shell den Backslash entfernen, grep
würde ein nicht entkoppeltes Dollarzeichen sehen, das das Zeilenende bedeutet, und mit jeder Eingabezeile übereinstimmen.)
Wenn Ihr Terminal Farben unterstützt, werfen Sie auch Farben auf,
grep --color=auto -P "(\:|\/|\?|\#|\@|\!|\\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])"
Hier ist die Erklärung meiner Regex von regex101.com
/(\:|\/|\?|\#|\@|\!|\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\])/gm 1st Capturing Group (\:|\/|\?|\#|\@|\!|\$|\&|\"|\(|\)|\*|\+|\,|\;|\=|\%|\[|\]) \: matches the character : literally (case sensitive) \/ matches the character / literally (case sensitive) \? matches the character ? literally (case sensitive) \# matches the character # literally (case sensitive) \@ matches the character @ literally (case sensitive) \! matches the character ! literally (case sensitive) \$ matches the character $ literally (case sensitive) \& matches the character & literally (case sensitive) \" matches the character " literally (case sensitive) \( matches the character ( literally (case sensitive) \) matches the character ) literally (case sensitive) \* matches the character * literally (case sensitive) \+ matches the character + literally (case sensitive) \, matches the character , literally (case sensitive) \; matches the character ; literally (case sensitive) \= matches the character = literally (case sensitive) \% matches the character % literally (case sensitive) \[ matches the character [ literally (case sensitive) \] matches the character ] literally (case sensitive)
Kommentare
- Nein, mit Standard-ERE können Sie ‚ dem Schließen nicht entkommen
]
mit Backslash. Backslash ist kein spezieller Ausdruck in Klammern. Um ein]
in einem Klammerausdruck zu haben, muss es zuerst sein:[]other]
, nicht[ot\]her]
. Das ‚ unterscheidet sich von PCREs, die standardmäßig in regex101 beschrieben werden. - Es würde mit
pcregrep
oder GNUgrep -P
. Und in gewissem Sinne ist das Perl-Verhalten einfacher: Ein Backslash macht ein Sonderzeichen immer normal. - Korrigiert zu -P, tut mir leid, ich verwechsle -E und -P