Wie entferne ich alle Zeilen aus der Textdatei, die die Wörter "cat" und "rat" enthält?
Wie entferne ich alle Zeilen aus der Textdatei, die die Wörter "cat" und "rat" enthält?
Antworten:
grep
AnsatzUm eine Kopie der Datei ohne Zeilen zu erstellen, die mit "cat" oder "rat" übereinstimmen, können Sie grep
umgekehrt ( -v
) und mit der Ganzwortoption ( -w
) vorgehen .
grep -vwE "(cat|rat)" sourcefile > destinationfile
Die Ganzwort-Option stellt sicher, dass es nicht passt cats
oder grateful
zum Beispiel. Die Ausgabeumleitung Ihrer Shell wird verwendet ( >
), um sie in eine neue Datei zu schreiben. Wir benötigen die -E
Option, um die erweiterten regulären Ausdrücke für die (one|other)
Syntax zu aktivieren .
sed
AnsatzUm die vorhandenen Zeilen zu entfernen, können Sie alternativ Folgendes verwenden sed -i
:
sed -i "/\b\(cat\|rat\)\b/d" filename
Das \b
setzt Wortgrenzen und die d
Operation löscht die Zeile, die dem Ausdruck zwischen den Schrägstrichen entspricht. cat
und rat
beide stimmen mit der (one|other)
Syntax überein, die wir anscheinend mit Backslashes umgehen müssen.
Tipp: Verwenden Sie diese Option sed
ohne -i
Operator, um die Ausgabe des Befehls zu testen, bevor Sie die Datei überschreiben.
(Basierend auf Sed - Löschen einer Zeile, die eine bestimmte Zeichenfolge enthält )
Verwenden Sie zum Testen nur im Terminal:
sed '/[cr]at/d' file_name
Um diese Zeilen wirklich aus der Datei zu entfernen, verwenden Sie:
sed -i '/[cr]at/d' file_name
Überlegen Sie, ob Sie eine Datei mit haben file_name
und nach mouse suchen möchten, aber gleichzeitig nur wenige Zeilen von mouse mit anderen Wörtern wie cat
und rat
und diese nicht in Ihrer Ausgabe anzeigen möchten.
grep -r mouse file_name | grep -vE "(cat|rat)"
Arbeitet in /bin/sh
, was dash
auf Ubuntu, sowie ksh
und bash
. Etwas umständlich, dass Sie mehrere Testfälle für jedes Wort in case
Anweisung schreiben müssen, aber portabel. Funktioniert mit Fällen, in denen das Wort allein in der Zeile, am Anfang, am Ende oder in der Mitte der Zeile vorkommt und ignoriert, wo es Teil eines anderen Wortes sein könnte.
#!/bin/sh
line_handler(){
# $1 is line read, prints to stdout
case "$1" in
cat|cat\ *|*\ cat\ *|*\ cat) true;; # do nothing if cat or rat in line
rat|rat\ *|*\ rat\ *|*\ rat) true;;
*) printf "%s\n" "$1"
esac
}
readlines(){
# $1 is input file, the rest is words we want to remove
inputfile="$1"
shift
while IFS= read -r line;
do
line_handler "$line" "$@"
done < "$inputfile"
[ -n "$line" ] && line_handler "$line"
}
readlines "$@"
Und so funktioniert es:
$ cat input.txt
the big big fat cat
the cat who likes milk
jumped over gray rat
concat
this is catchy
rat
rational
irrational
$ ./dellines.sh input.txt
concat
this is catchy
rational
irrational