Как удалить все файлы, не содержащие указанный текст.
Я понимаю решение по удалению файлов с указанным текстом, но мне нужно удалить файлы, НЕ содержащие указанный шаблон.
Следующая команда создает список файлов, не содержащих «успешный запуск»:
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