найдите шаблон в файлах и удалите

#bash #awk #grep

Вопрос:

у меня есть каталог, содержащий текстовые файлы, которые содержат необработанный http-запрос следующим образом

 POST /test HTTP/1.1
Host: host.com
Content-Type: application/x-www-form-urlencoded
Accept-Language: en-US, gHNEY;q=0.9, *;q=0.5
Accept-Charset: utf-8, iso-8859-1;q=0.5, 3AG19;q=0.2, *;q=0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5)
Accept: */*, text/XppPa

param1=ffffamp;
 

как вы видите, этот файл с именем as 2b0c9d9254abb4a775023177380c2598.txt является url-адресом md5sum, и сейчас это не так, но я хочу упомянуть об этом

я хочу найти файлы, которые есть not containing parameters , и удалить их, чтобы остальные файлы в этом каталоге были только файлами, содержащими параметры

то, что я попробовал, — это уникальное значение grep, найденное в этих файлах, содержащих параметры, и я обнаружил, что общим является символ amp; , который записывается рядом со значением параметра

поэтому я попробовал выполнить следующую команду и не смог grep -lrIvE 'amp;' . | xargs -0 rm -f -- , результат был ./2b0c9d9254abb4a775023177380c2598.txt'$'n': File name too long

и когда я добавил заглавную букву Z в grep, я удалил все файлы

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

Спасибо

Комментарии:

1. Вы не можете использовать -0 опцию xargs «без -Z опции grep «. Это не сработало бы. Ваша проблема в том, что grep -v совпадают все строки, не содержащие amp; . И во всех ваших файлах есть хотя бы один.

Ответ №1:

Примечание: вы не можете использовать -0 опцию xargs «без -Z опции grep «. Разделители записей не будут совпадать.

Ваша проблема в том, что grep -v совпадают все строки, не содержащие amp; . И во всех ваших файлах есть по крайней мере один. Вместо поиска несоответствующих строк вы можете искать совпадающие и удалять файлы, только если они не найдены:

 find . -type f -print0 | while IFS= read -r -d '' f; do
  grep -Iq 'amp;' "$f" || printf 'rm -f %sn' "$f"
done
 

Замените printf 'rm -f %sn' "$f" на rm -f "$f" один раз, когда вы убедитесь, что он делает то, что вы хотите.

Комментарии:

1. Почему петля? find . -type f ! -exec grep -q 'amp;' {} ; -exec echo rm -rf {} делает то же самое.

2. @oguzismail, который возвращает тест назад; попробуйте find . -type f ( -exec grep -q 'amp;' {} ; -o -print ) , и если он напечатает правильные имена, замените -print на -delete .

3. @Гордон Да, спасибо. Обновил его, скобки не нужны.

4. @oguzismail Ах, я понимаю; отрицание -exec grep должно работать нормально.

5. @RenaudPacalet моем варианте -o («или») между оператором -exec grep и -delete ; неявный «и» имеет более высокий приоритет, чем -o так, без скобок было бы: (это файл и содержит «amp;») или удалить его-что бы удалить все, что не является файлом или не содержит символ «amp;».