Como remover linhas do arquivo de texto que contém palavras específicas através do terminal?

72

Como remover todas as linhas do arquivo de texto que contêm as palavras "gato" e "rato"?

PersonX
fonte
Parece suspeito como uma tarefa de casa. Lembre-se de atribuir sua resposta às pessoas legais do Askubuntu.
Zwets
Que faz parte do grande projeto, sou novo no ambiente Linux.
PersonX 07/10

Respostas:

100

grep aproximação

Para criar uma cópia do arquivo sem linhas correspondentes a "gato" ou "rato", pode-se usar grepem 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 catsou, gratefulpor exemplo. O redirecionamento de saída do seu shell é usado ( >) para gravá-lo em um novo arquivo. Precisamos da -Eopção de ativar as expressões regulares estendidas para a (one|other)sintaxe.

sed aproximação

Como alternativa, para remover as linhas no local, pode-se usar sed -i:

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

Os \blimites conjuntos de palavras e a doperação apaga a linha correspondente a expressão entre as barras. cate ratambos estão sendo correspondidos pela (one|other)sintaxe que aparentemente precisamos escapar com barras invertidas.

Dica: use sedsem o -ioperador 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 )

gertvdijk
fonte
Gostaria de saber se existe uma maneira de conseguir a remoção do arquivo de origem E gerar o arquivo com correspondências. Provavelmente não, mas seria útil (por exemplo, quando você obtém um arquivo muito grande, está dividindo-o com base no conteúdo).
Sridhar Sarnobat
11
@ Sridhar-Sarnobat Oh, você pode. Use tee e subshells para copiar stdout. Em um você filtra, no outro o inverso. O uso de tee e subshells demonstrados em um caso de uso não relacionado, demonstrado aqui: blog.g3rt.nl/…
gertvdijk
15

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

Experimente o vim-way:

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

Considere se você tem arquivo com file_namee você deseja procurar mouse, mas no mesmo tempo algumas linhas de rato tendo outras palavras, como cate rate 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)"
Indrajeet Gour
fonte
0

maneira shell portátil

Funciona em /bin/sh, que está dashno Ubuntu, bem como ksh, e bash. Um pouco estranho que você precise escrever vários casos de teste para cada palavra na casedeclaraçã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
Sergiy Kolodyazhnyy
fonte