Odpowiedzi:
grep
podejścieAby utworzyć kopię pliku bez wierszy pasujących do „cat” lub „rat”, można użyć funkcji grep
reverse ( -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ć cats
lub grateful
na przykład. Wyjściowe przekierowanie powłoki jest używane ( >
) do zapisania jej w nowym pliku. Potrzebujemy -E
opcji włączenia rozszerzonych wyrażeń regularnych dla (one|other)
składni.
sed
podejścieAlternatywnie, aby usunąć linie w miejscu, można użyć sed -i
:
sed -i "/\b\(cat\|rat\)\b/d" filename
Te \b
granice zestawy słowo i d
działanie usuwa wiersz pasujący wyraz między ukośniki. cat
i rat
oba są dopasowane do (one|other)
składni, której najwyraźniej potrzebujemy, aby uciec z odwrotnym ukośnikiem.
Wskazówka: użyj sed
bez -i
operatora, aby przetestować dane wyjściowe polecenia przed zastąpieniem pliku.
(Na podstawie Sed - Usuń wiersz zawierający określony ciąg )
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
Zastanów się, czy masz plik file_name
i chcesz wyszukać mysz, ale jednocześnie kilka wierszy myszy ma inne słowa, takie jak cat
i, rat
a nie chcesz, aby były widoczne w wynikach, więc jedynym sposobem na to jest -
grep -r mouse file_name | grep -vE "(cat|rat)"
Działa w /bin/sh
, który jest dash
na Ubuntu, a także ksh
i bash
. Nieco niewygodne, że musisz napisać wiele przypadków testowych dla każdego słowa w case
instrukcji, 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