Jak usunąć wiersze z pliku tekstowego zawierającego określone słowa przez terminal?

72

Jak usunąć wszystkie wiersze z pliku tekstowego zawierającego słowa „kot” i „szczur”?

PersonX
źródło
To brzmi podejrzanie jak zadanie domowe. Pamiętaj, aby przypisać swoją odpowiedź miłym ludziom z Askubuntu.
zwets
To część dużego projektu, jestem nowy w środowisku Linux.
PersonX

Odpowiedzi:

100

grep podejście

Aby utworzyć kopię pliku bez wierszy pasujących do „cat” lub „rat”, można użyć funkcji grepreverse ( -v) i opcji całego słowa ( -w).

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

Opcja całego słowa gwarantuje , że nie będzie pasować catslub gratefulna przykład. Wyjściowe przekierowanie powłoki jest używane ( >) do zapisania jej w nowym pliku. Potrzebujemy -Eopcji włączenia rozszerzonych wyrażeń regularnych dla (one|other)składni.

sed podejście

Alternatywnie, aby usunąć linie w miejscu, można użyć sed -i:

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

Te \bgranice zestawy słowo i ddziałanie usuwa wiersz pasujący wyraz między ukośniki. cati ratoba są dopasowane do (one|other)składni, której najwyraźniej potrzebujemy, aby uciec z odwrotnym ukośnikiem.

Wskazówka: użyj sedbez -ioperatora, aby przetestować dane wyjściowe polecenia przed zastąpieniem pliku.

(Na podstawie Sed - Usuń wiersz zawierający określony ciąg )

gertvdijk
źródło
Zastanawiam się, czy istnieje sposób na usunięcie zarówno pliku źródłowego, jak i wygenerowanie pliku z dopasowaniami. Prawdopodobnie nie, ale przydałoby się (np. Gdy dostajesz zbyt duży plik, dzielisz go na podstawie zawartości).
Sridhar Sarnobat
1
@ Sridhar-Sarnobat Och, możesz. Użyj tee i podpowłoki, aby skopiować standardowe wyjście. W jednym filtrujesz, w drugim odwrotnie. Wykorzystanie tee i podpowłoki pokazane w niepowiązanym przypadku użycia pokazanym tutaj: blog.g3rt.nl/…
gertvdijk
15

Aby przetestować tylko w terminalu, użyj:

sed '/[cr]at/d' file_name

Aby naprawdę usunąć te linie z pliku, użyj:

sed -i '/[cr]at/d' file_name
Radu Rădeanu
źródło
5

Wypróbuj vim-way:

ex +"g/[cr]at/d" -scwq file.txt
kenorb
źródło
0

Zastanów się, czy masz plik file_namei chcesz wyszukać mysz, ale jednocześnie kilka wierszy myszy ma inne słowa, takie jak cati, rata nie chcesz, aby były widoczne w wynikach, więc jedynym sposobem na to jest -

grep -r mouse file_name | grep -vE "(cat|rat)"
Indrajeet Gour
źródło
0

przenośny sposób powłoki

Działa w /bin/sh, który jest dashna Ubuntu, a także kshi bash. Nieco niewygodne, że musisz napisać wiele przypadków testowych dla każdego słowa w caseinstrukcji, ale przenośne. Działa z przypadkami, w których słowo pojawia się samodzielnie na linii, na początku, na końcu linii lub na środku linii i ignoruje miejsce, w którym może być częścią innego słowa.

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

I tak to działa:

$ 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
źródło