Wie entferne ich Zeilen aus der Textdatei, die bestimmte Wörter enthalten?

72

Wie entferne ich alle Zeilen aus der Textdatei, die die Wörter "cat" und "rat" enthält?

PersonX
quelle
Das klingt verdächtig nach einer Hausaufgabe. Bitte denken Sie daran, Ihre Antwort den netten Leuten bei Askubuntu zuzuschreiben.
zwets
Das ist ein Teil des großen Projekts. Ich bin neu in der Linux-Umgebung.
PersonX

Antworten:

100

grep Ansatz

Um eine Kopie der Datei ohne Zeilen zu erstellen, die mit "cat" oder "rat" übereinstimmen, können Sie grepumgekehrt ( -v) und mit der Ganzwortoption ( -w) vorgehen .

grep -vwE "(cat|rat)" sourcefile > destinationfile

Die Ganzwort-Option stellt sicher, dass es nicht passt catsoder gratefulzum Beispiel. Die Ausgabeumleitung Ihrer Shell wird verwendet ( >), um sie in eine neue Datei zu schreiben. Wir benötigen die -EOption, um die erweiterten regulären Ausdrücke für die (one|other)Syntax zu aktivieren .

sed Ansatz

Um die vorhandenen Zeilen zu entfernen, können Sie alternativ Folgendes verwenden sed -i:

sed -i "/\b\(cat\|rat\)\b/d" filename

Das \bsetzt Wortgrenzen und die dOperation löscht die Zeile, die dem Ausdruck zwischen den Schrägstrichen entspricht. catund ratbeide stimmen mit der (one|other)Syntax überein, die wir anscheinend mit Backslashes umgehen müssen.

Tipp: Verwenden Sie diese Option sedohne -iOperator, 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 )

gertvdijk
quelle
Ich frage mich, ob es eine Möglichkeit gibt, sowohl das Entfernen aus der Quelldatei als auch das Generieren der Datei mit Übereinstimmungen zu erreichen. Wahrscheinlich nicht, aber es wäre nützlich (z. B. wenn Sie eine zu große Datei erhalten, teilen Sie sie basierend auf dem Inhalt).
Sridhar Sarnobat
1
@ Sridhar-Sarnobat Oh, das kannst du. Verwenden Sie Tee und Subshells, um stdout zu kopieren. In einem filtern Sie, in dem anderen das Gegenteil. Die Verwendung von Tee und Subshells wurde in einem nicht verwandten Anwendungsfall demonstriert: blog.g3rt.nl/…
gertvdijk
15

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
Radu Rădeanu
quelle
5

Probieren Sie die vim-way:

ex +"g/[cr]at/d" -scwq file.txt
Kenorb
quelle
0

Überlegen Sie, ob Sie eine Datei mit haben file_nameund nach mouse suchen möchten, aber gleichzeitig nur wenige Zeilen von mouse mit anderen Wörtern wie catund ratund diese nicht in Ihrer Ausgabe anzeigen möchten.

grep -r mouse file_name | grep -vE "(cat|rat)"
Indrajeet Gour
quelle
0

tragbare Schale Weg

Arbeitet in /bin/sh, was dashauf Ubuntu, sowie kshund bash. Etwas umständlich, dass Sie mehrere Testfälle für jedes Wort in caseAnweisung 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
Sergiy Kolodyazhnyy
quelle