Как удалить все строки из текстового файла, содержащего слова «кошка» и «крыса»?
grep
подход Чтобы создать копию файла без строк, совпадающих с «кошкой» или «крысой», можно использовать grep
в обратном порядке (-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
Попробуйте vim-way:
ex +"g/[cr]at/d" -scwq file.txt
Подумайте, есть ли у вас файл с 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
Использование awk для исключения строк, содержащих определенные слова:
$ awk '!/\<(cat|rat)\>/{print $0}' ./input.txt
синтаксис awk:
!/regex/
Печатать только строки, не соответствующие регулярному выражению. |
Оператор альтернативы, используемый для указания альтернатив. (...)
Группировка, например группировка операторов чередования. \<
Соответствует пустой строке в начале слова. \>
Соответствует пустой строке в конце слова. {...}
Оператор действия. cat logs.txt | grep 'your regex' > logs_regex.txt
Это создаст новый файл logs_regex.txt, который является копией вашего файла logs.txt только со строками, содержащими ваше регулярное выражение