Удаление файла в каталоге mutliple с определенной строкой - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть дерево папок вроде:

00 -- 0
   -- 1
   ...
   -- 9
 ...
99 -- 0 
   -- 1
   ...
   -- 9

В каждой папке есть файлы .ini с каким-то текстом od.

Как удалить файлы, которые получили # в начале второй строки?

Я пытался использовать:

for i in {00..99}; do for b in {0..9}; do grep -LZ -- # *.ini | xargs
-r0 rm; done; done

, но это не сработало.Мне интересно использовать sed и awk, но я не знаю как.

1 Ответ

0 голосов
/ 18 декабря 2018

С достаточно недавними Awk и GNU find вы можете сделать

awk 'FNR==2 { if ($0 ~ /^#/) printf "%s\0", FILENAME; nextfile }' [0-9][0-9]/[0-9]/*.ini |
xargs -r0 echo rm

nextfile оператор является расширением POSIX, но может отсутствовать в очень старых реализациях Awk,Если ваши файлы маленькие, возможно, просто извлеките nextfile и согласитесь с незначительной неэффективностью, которую мы читаем до конца каждого файла, даже если нам действительно нужно исследовать вторую строку.

-0 опция xargs является расширением GNU.Если ваши имена файлов гарантированно не содержат символов новой строки, вы, вероятно, можете обойтись без

awk 'FNR==2 { if ($0 ~ /^#/) print FILENAME; nextfile }' [0-9][0-9]/[0-9]/*.ini |
xargs -r echo rm

Наконец, удалите echo, чтобы фактически удалить файлы, которые он печатает.

В некоторых другихподробно, Awk обрабатывает каждый входной файл по одной строке за раз и оценивает скрипт для каждого отдельно.Встроенная переменная FNR устанавливается на текущий номер строки в файле, а FILENAME - имя текущего файла.Переменная $0 содержит всю строку, и мы проверяем, соответствует ли она регулярному выражению ^# (начало строки, за которым сразу следует буквальный символ #);если это так, мы печатаем FILENAME (в противном случае для этого файла не выводится).Команда nextfile закрывает текущий файл и сразу переходит к первой строке ввода следующего файла в списке аргументов (или останавливает обработку, если имена файлов не обрабатываются).

Если у вас многоиз подходящих файлов вы не можете использовать подобный шаблон (вы получаете «список аргументов слишком длинный»);если это так, возможно, просто вернитесь к тому циклу, который у вас был.

Непосредственная ошибка в вашей попытке состоит в том, что вам нужны кавычки около # (в противном случае он помечает оставшуюся часть строки как комментарий);но, конечно, ваш grep ищет этот символ в любом месте файла, и вы не указали путь к файлу для проверки.С исправленными непосредственными ошибками это будет

# Don't use, still broken
for i in stuff; do
    for b in more stuff; do
        grep -LZ '#' "$i/$b"/*.ini
    done
done |
# or simply grep -LZ '#' [0-9][0-9]/[0-9]/*.ini
xargs -r0 echo rm

, но опять же, вы не можете легко исправить это, чтобы посмотреть только на вторую строку каждого файла.(Обратите также внимание, как я запускаю финал xargs вне финала done.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...