Sehr neu in UNIX, aber nicht neu in der Programmierung. Terminal auf dem MacBook verwenden. Zum Verwalten und Durchsuchen von Wortlisten für die Kreuzworträtselkonstruktion versuche ich, mit dem Befehl Grep und seinen Variationen vertraut zu werden. Scheint ziemlich unkompliziert zu sein, aber ich muss mich schon früh mit dem befassen, was ich für einen einfachen Fall hielt.
Wenn ich eintrete
grep "^COW" masternospaces.txt
Ich bekomme, was ich will: eine Liste aller Wörter, die mit COW beginnen.
Aber wenn ich eintrete
grep "COW$" masternospaces.txt
Ich erwarte eine Liste von Wörtern, die mit COW enden (es gibt viele solcher Wörter), und es wird überhaupt nichts zurückgegeben.
Die Datei ist eine reine Textdatei, in der jede Zeile nur ein Wort (oder eine Wortgruppe ohne Leerzeichen) in Großbuchstaben enthält.
Irgendeine Idee, was hier passieren könnte?
hexdump
Sie genau überprüfen, wie Ihre Zeilenenden formatiert sind. Ich schlage vor , Sie meinen Lieblings Format verwenden:hexdump -e '"%08_ad (0x%08_ax) "8/1 "%02x "" "8/1 "%02x "' -e '" "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
. Überprüfen Sie bei der Ausgabe die Zeilenenden:0a
->LF
,0d
->CR
.Antworten:
Wie @steeldriver bereits erwähnte, wird das Problem wahrscheinlich durch einen anderen Zeilenendestil als what verursacht
grep
erwartet.Um die Zeilenenden zu überprüfen
Mit können
hexdump
Sie genau überprüfen, wie Ihre Zeilenenden formatiert sind. Ich schlage vor, Sie verwenden mein Lieblingsformat:Überprüfen Sie bei der Ausgabe die Zeilenenden:
0a
->LF
,0d
->CR
. Ein sehr kurzes Beispiel würde ungefähr so aussehen:Beachten Sie die Zeilenenden im DOS-Format:
0d 0a
.Zeilenenden ändern
Sie können hier oder hier nach verschiedenen Methoden zum Ändern von Zeilenenden mit verschiedenen Werkzeugen suchen, aber für eine einmalige Sache können Sie immer vi / vim verwenden:
Grep, ohne etwas zu ändern
Wenn Sie
grep
unabhängig vom Zeilenende nur eine Übereinstimmung finden möchten , können Sie die Zeilenenden immer wie folgt festlegen:Wenn eine leere Zeile angezeigt wird, können Sie anhand der folgenden
-v
Optionen überprüfen, ob Sie tatsächlich eine Übereinstimmung gefunden habencat
:Mein persönlicher Favorit
Sie können die Ausgabe auch mit den
sed
folgenden Methoden standardisieren :Woher
^M
kommt man, wenn manCtrl-V Ctrl-M
auf der Tastatur tippt ?Hoffe das hilft!
quelle
[[:cntrl:]]
@ user43791 Vorschlag ausprobiert und er passt immer noch nicht zu mir. Das macht keinen Sinn. Ich benutze GNU grep 2.20 und analysiere die Ausgabe von nDPI, die in eine Textdatei geschrieben wurdecat -v yourfile.ext
, was sehen Sie?file
.Obwohl Sie mit grep die 'Standard'-RegEx-Syntax verwenden können (wie in der Antwort von @ user43791) ), verfügt grep auch über andere Bezeichner, um die Eingabegrenzen zu kennzeichnen.
Die Matcher für den Anfang und das Ende der gesamten Zeile lauten
\`
(Backtick) (anstelle von^
) und\'
(Apostroph) (anstelle von)$
).Für Ihren ursprünglichen Befehl würden Sie also Folgendes verwenden:
grep "COW\'" masternospaces.txt
Randnotiz: Es ist auch wichtig zu beachten, dass
?
und+
wird wörtlich behandelt, es sei denn, Sie entkommen ihnen mit\?
und\+
machen sie zu ihren RegEx-ähnlichen Selektor-Gegenstücken.Quelle:
grep
Syntax für reguläre Ausdrückequelle
Ein anderer Weg, das
\r
vor dem grep zu entfernen :Ich mag es, dass es sehr klar ist, da ich mich nicht lange an solche Dinge erinnere
[[:cntrl:]]
.quelle
"COW $" Wenn die Bash den Parameter für grep gesetzt hat, wurde dies als "COW" interpretiert, wobei "$" als "" behandelt wird, da $ ein Escape-Simbol ist. Wenn $ nichts mit einbezieht, wird es von der Bash-Shell als leere Zeichenfolge interpretiert. Verwenden Sie stattdessen grep 'COW $' masternospaces.txt.
quelle
$
, würde es von bash in Ruhe gelassen und von grep verwendet. Überzeugen Sie sich selbst:echo "COW$"
- Der$
wird noch da sein.In BSD grep müssen Sie "$" entkoppeln und Ihre Zeichenfolge in doppelte Anführungszeichen setzen:
quelle
$
wird für die Shell nicht besonders sein, da das Zeug danach kein gültiger Shell-Variablenname ist. Die Verwendung von einfachen Anführungszeichen um statische Zeichenfolgen ist eine bessere Idee, macht hier jedoch keinen Unterschied.