Come rimuovere le righe dal file di testo contenente parole specifiche tramite il terminale?


72

Come rimuovere tutte le righe dal file di testo contenente le parole "gatto" e "ratto"?


Sembra sospettosamente come un compito a casa. Ricorda di attribuire la tua risposta alle persone simpatiche di Askubuntu.
zwets,

Che parte del grande progetto, sono nuovo nell'ambiente Linux.
PersonX

Risposte:


100

grep approccio

Per creare una copia del file senza le righe corrispondenti a "cat" o "rat", si può usare grepin reverse ( -v) e con l'opzione intera-parola ( -w).

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

L'opzione a parola intera assicura che non corrisponda catso, gratefulad esempio. Viene utilizzato il reindirizzamento dell'output della shell ( >) per scriverlo in un nuovo file. Abbiamo bisogno -Edell'opzione per abilitare le espressioni regolari estese per la (one|other)sintassi.

sed approccio

In alternativa, per rimuovere le linee sul posto è possibile utilizzare sed -i:

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

I \bconfini set di parole e l' doperazione elimina la linea di corrispondenza l'espressione tra le slash. cate ratsono entrambi accompagnati dalla (one|other)sintassi di cui apparentemente dobbiamo scappare con le barre rovesciate.

Suggerimento: utilizzare sedsenza l' -ioperatore per testare l'output del comando prima di sovrascrivere il file.

(Basato su Sed - Elimina una riga contenente una stringa specifica )


Mi chiedo se c'è un modo per ottenere sia la rimozione dal file sorgente sia generare il file con le corrispondenze. Probabilmente no, ma sarebbe utile (ad esempio quando si ottiene un file che sta diventando troppo grande, lo si divide in base al contenuto).
Sridhar Sarnobat,

1
@ Sridhar-Sarnobat Oh, puoi. Usa tee e subshells per copiare stdout. In uno si filtra, nell'altro il contrario. L'uso di tee e subshells dimostrato in un caso d'uso non correlato dimostrato qui: blog.g3rt.nl/…
gertvdijk

15

Per eseguire il test solo nel terminale, utilizzare:

sed '/[cr]at/d' file_name

Per rimuovere davvero quelle righe dal file, usare:

sed -i '/[cr]at/d' file_name

5

Prova la vim-way:

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

0

Considera se hai un file con file_namee vuoi cercare il mouse ma allo stesso tempo poche righe del mouse con altre parole simili cate rate non vuoi vedere quelle nel tuo output, quindi l'unico modo per farlo è -

grep -r mouse file_name | grep -vE "(cat|rat)"

0

modo shell portatile

Funziona in /bin/sh, che è dashsu Ubuntu, così come kshe bash. Leggermente imbarazzante che tu debba scrivere più casi di test per ogni parola in caseaffermazione ma portatile. Funziona con i casi in cui la parola appare sola sulla linea, all'inizio, alla fine della linea o al centro della linea e ignora dove potrebbe far parte di un'altra parola.

#!/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 "$@"

Ed è così che funziona:

$ 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.