Como remover todas as linhas do arquivo de texto que contêm as palavras "gato" e "rato"?
Como remover todas as linhas do arquivo de texto que contêm as palavras "gato" e "rato"?
Respostas:
grep
aproximaçãoPara criar uma cópia do arquivo sem linhas correspondentes a "gato" ou "rato", pode-se usar grep
em reverse ( -v
) e com a opção de palavra inteira ( -w
).
grep -vwE "(cat|rat)" sourcefile > destinationfile
A opção de palavra inteira garante que não corresponda cats
ou, grateful
por exemplo. O redirecionamento de saída do seu shell é usado ( >
) para gravá-lo em um novo arquivo. Precisamos da -E
opção de ativar as expressões regulares estendidas para a (one|other)
sintaxe.
sed
aproximaçãoComo alternativa, para remover as linhas no local, pode-se usar sed -i
:
sed -i "/\b\(cat\|rat\)\b/d" filename
Os \b
limites conjuntos de palavras e a d
operação apaga a linha correspondente a expressão entre as barras. cat
e rat
ambos estão sendo correspondidos pela (one|other)
sintaxe que aparentemente precisamos escapar com barras invertidas.
Dica: use sed
sem o -i
operador para testar a saída do comando antes de substituir o arquivo.
(Baseado em Sed - exclua uma linha que contém uma sequência específica )
Para testar apenas no terminal, use:
sed '/[cr]at/d' file_name
Para realmente remover essas linhas do arquivo, use:
sed -i '/[cr]at/d' file_name
Considere se você tem arquivo com file_name
e você deseja procurar mouse, mas no mesmo tempo algumas linhas de rato tendo outras palavras, como cat
e rat
e você não quer ver aqueles em sua saída, então a única maneira de fazer isso é -
grep -r mouse file_name | grep -vE "(cat|rat)"
Funciona em /bin/sh
, que está dash
no Ubuntu, bem como ksh
, e bash
. Um pouco estranho que você precise escrever vários casos de teste para cada palavra na case
declaração, mas portátil. Trabalha com casos em que a palavra aparece sozinha na linha, no início, no final da linha ou no meio da linha e ignora onde pode fazer parte de outra palavra.
#!/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 "$@"
E é assim que funciona:
$ 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