Удалить все файлы, НЕ содержащие шаблон в содержимом

Удалить все файлы, НЕ содержащие шаблон в содержимом

Как удалить все файлы, не содержащие указанный текст.

Я понимаю решение по удалению файлов с указанным текстом, но мне нужно удалить файлы, НЕ содержащие указанный шаблон.

Следующая команда создает список файлов, не содержащих «успешный запуск»:

grep -c "successful run" *.out | grep -v ":1" > err.txt

Я хочу напрямую удалить эти файлы.

решение1

Ваш оригинальный подход к определению подходящих файлов

grep -c "successful run" *.out | grep -v ":1"

имеет изъяны. Основные опасения:

  • Что делать, если в одном файле есть две или более совпадающих строк? grep ":0"кажется, лучше соответствует условию в заголовке вашего вопроса («файлы, не содержащие шаблон»).
  • А если :1(или :0) есть в имени файла? Так grep ':0$'даже лучше.
  • А что, если в любом из имен файлов, переданных из первого, есть символ новой строки grep?

Я говорю, не полагайтесь на grep -c; полагайтесь на статус выхода, grepкоторый возникает, 1если не выбрано ни одной строки.

for f in *.out; do
   [ -f "$f" ] && {
      grep -q -- "successful run" "$f"
      [ "$?" -eq 1 ] && rm -i -- "$f"
   }
done

Примечания:

  • [ -f "$f" ] && …не позволит grepработать с каталогами, fifo и т.п., которые соответствуют *.out; только обычные файлы.
  • --Объясняется смысл и значениездесь. Это в случае, если есть файл с именем, начинающимся с -, его можно ошибочно принять за опцию. Другой способ решения этой проблемы — for f in ./*.out; do …. Таким образом, каждый развернутый файл $fначинается с , ./поэтому он не может начинаться с -.
  • Я использовал rm -iна всякий случай. После того, как вы протестируете решение, вы можете захотеть опустить -i.
  • grep … || rm …хуже. Когда происходит настоящая ошибка (например, отказ в доступе), статус выхода grepбольше 1; тогда вы, вероятно, не захотите удалять файл. Мое решение проверяет, является ли статус выхода точно 1.
  • Ваш исходный код не спускается в подкаталоги, как и мой. Если вам нужна рекурсия, то оболочка, которая ее поддерживает (например, Bash с shopt -s globstarи **) или решение, основанное на findбудет полезно.

решение2

Учитывая, что у ваших файлов либо один «успешный запуск», либо ни одного, то:

Чтобы найти соответствующие файлы, вы можете сделать следующее:

grep -l "successful run" *.out > err.txt

чтобы найти и удалить их:

grep -l "successful run" *.out | xargs rm

чтобы найти файлы без совпадений, выполните следующие действия:

grep -vl "successful run" *.out > ok.txt

чтобы найти и удалить их:

grep -vl "successful run" *.out | xargs rm

Флаги означают:

-l lists the files with matches
-v/--invert-match inverts the matching logic

Связанный контент