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

59

Como remover todas as linhas do arquivo de texto que contém as palavras "cat" e "rat"?

    
por PersonX 07.10.2013 / 21:35

5 respostas

80

grep approach

Para criar uma cópia do arquivo sem linhas correspondentes a "cat" ou "rat", pode-se usar grep no reverso ( -v ) e com a opção de palavra inteira ( -w ).

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

A opção de palavra inteira garante que ela não corresponda a cats ou grateful , por exemplo. O redirecionamento de saída do seu shell é usado ( > ) para gravar em um novo arquivo. Precisamos da opção -E para ativar as expressões regulares estendidas para a sintaxe (one|other) .

sed approach

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

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

O \b define limites de palavras e a operação d exclui a linha que corresponde à expressão entre as barras. cat e rat estão sendo correspondidos pela sintaxe (one|other) que aparentemente precisamos escapar com barras invertidas.

Dica: use sed sem o operador -i para testar a saída do comando antes de sobrescrever o arquivo.

(Baseado em Sed - Excluir uma linha contendo uma string específica )

    
por gertvdijk 07.10.2013 / 21:53
12

Para testar apenas no terminal, use:

sed '/[cr]at/d' file_name

Para remover realmente essas linhas do arquivo, use:

sed -i '/[cr]at/d' file_name
    
por Radu Rădeanu 07.10.2013 / 21:49
5

Experimente o vim-way:

ex +"g/[cr]at/d" -scwq file.txt
    
por kenorb 30.04.2015 / 00:26
0

Considere se você tem um arquivo com file_name e deseja pesquisar por mouse, mas ao mesmo tempo, algumas linhas do mouse têm outras palavras como cat e rat e você não deseja ver aquelas em seu saída, então a única maneira de fazer isso é -

grep -r mouse file_name | grep -vE "(cat|rat)"
    
por Indrajeet Gour 26.10.2015 / 12:33
0

caminho de shell portátil

Funciona em /bin/sh , que é dash no Ubuntu, bem como ksh e bash . Um pouco estranho que você tenha que escrever vários casos de teste para cada palavra na instrução case , mas portável. Funciona com casos em que a palavra aparece sozinha na linha, no começo, no final da linha ou no meio da linha, e ignora onde ela pode fazer parte de outra palavra.

#!/bin/sh
line_handler(){
   #  is line read, prints to stdout
    case "" in
        cat|cat\ *|*\ cat\ *|*\ cat) true;; # do nothing if cat or rat in line
        rat|rat\ *|*\ rat\ *|*\ rat) true;; 
        *) printf "%s\n" ""
    esac
}

readlines(){
    #  is input file, the rest is words we want to remove
    inputfile=""
    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
    
por Sergiy Kolodyazhnyy 09.11.2017 / 04:58