Come rimuovere tutte le righe dal file di testo contenente le parole "gatto" e "ratto"?
Come rimuovere tutte le righe dal file di testo contenente le parole "gatto" e "ratto"?
Risposte:
grep
approccioPer creare una copia del file senza le righe corrispondenti a "cat" o "rat", si può usare grep
in reverse ( -v
) e con l'opzione intera-parola ( -w
).
grep -vwE "(cat|rat)" sourcefile > destinationfile
L'opzione a parola intera assicura che non corrisponda cats
o, grateful
ad esempio. Viene utilizzato il reindirizzamento dell'output della shell ( >
) per scriverlo in un nuovo file. Abbiamo bisogno -E
dell'opzione per abilitare le espressioni regolari estese per la (one|other)
sintassi.
sed
approccioIn alternativa, per rimuovere le linee sul posto è possibile utilizzare sed -i
:
sed -i "/\b\(cat\|rat\)\b/d" filename
I \b
confini set di parole e l' d
operazione elimina la linea di corrispondenza l'espressione tra le slash. cat
e rat
sono entrambi accompagnati dalla (one|other)
sintassi di cui apparentemente dobbiamo scappare con le barre rovesciate.
Suggerimento: utilizzare sed
senza l' -i
operatore per testare l'output del comando prima di sovrascrivere il file.
(Basato su Sed - Elimina una riga contenente una stringa specifica )
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
Considera se hai un file con file_name
e vuoi cercare il mouse ma allo stesso tempo poche righe del mouse con altre parole simili cat
e rat
e non vuoi vedere quelle nel tuo output, quindi l'unico modo per farlo è -
grep -r mouse file_name | grep -vE "(cat|rat)"
Funziona in /bin/sh
, che è dash
su Ubuntu, così come ksh
e bash
. Leggermente imbarazzante che tu debba scrivere più casi di test per ogni parola in case
affermazione 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