Как удалить все строки из текстового файла, содержащего слова «кошка» и «крыса»?
Как удалить все строки из текстового файла, содержащего слова «кошка» и «крыса»?
Ответы:
grep
подходЧтобы создать копию файла без строк, совпадающих с «кошкой» или «крысой», можно использовать метод grep
reverse ( -v
) и с параметром целого слова ( -w
).
grep -vwE "(cat|rat)" sourcefile > destinationfile
Параметр «целое слово» гарантирует, что он не будет совпадать cats
или, grateful
например. Перенаправление вывода вашей оболочки используется ( >
) для записи его в новый файл. Нам нужна -E
опция для включения расширенных регулярных выражений для (one|other)
синтаксиса.
sed
подходВ качестве альтернативы, чтобы удалить строки на месте можно использовать sed -i
:
sed -i "/\b\(cat\|rat\)\b/d" filename
Эти \b
границы множества слов и d
операция удаляют строку , соответствующее выражение между косой чертой. cat
и rat
оба соответствуют (one|other)
синтаксису, который мы, очевидно, должны избежать с помощью обратной косой черты
Совет: используйте sed
без -i
оператора, чтобы проверить вывод команды перед перезаписью файла.
(На основе Sed - удалить строку, содержащую определенную строку )
Для проверки только в терминале используйте:
sed '/[cr]at/d' file_name
Чтобы действительно удалить эти строки из файла, используйте:
sed -i '/[cr]at/d' file_name
Рассмотрим , если у вас есть файл с , file_name
и вы хотите найти мышь , но в то же время несколько строк из мыши , имеющие другие слова , как cat
и rat
и вы не хотите , чтобы увидеть тех , кто в вашем выводе, так что один из способов сделать это -
grep -r mouse file_name | grep -vE "(cat|rat)"
Работает в /bin/sh
, который есть dash
на Ubuntu, а также ksh
, и bash
. Немного неловко, что вам приходится писать несколько тестов для каждого слова в case
выражении, но переносимо. Работает со случаями, когда слово появляется отдельно в строке, в начале, конце строки или в середине строки, и игнорирует, где оно может быть частью другого слова.
#!/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 "$@"
И вот как это работает:
$ 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