Удалить каталоги через сопоставление с шаблоном | используя bash скрипт / Python - PullRequest
0 голосов
/ 01 марта 2020

Предполагая, что входной файл * .txt содержит

//this text file usually contains unique id's
1effaj
21easd
231asd
71823aq

Один из моих главных каталогов содержит дочерние каталоги, как показано ниже

hello_1afadf
ring_1effaj
chain_asd123

Используя файл * .txt в качестве ввода, я хочу удалить все каталоги 1-го уровня, которые либо соответствуют, либо не соответствуют шаблону выше

Если я хочу удалить из текстового файла все каталоги, которые соответствуют шаблону, то следует удалить / удалить только «ring_1effaj».

Или кто-то может подсказать, как использовать несколько индексов массива, если строки этого входного текста хранятся в нескольких массивах.

rm -rf $(ls -aI "*_${b[1]}")

1 Ответ

1 голос
/ 01 марта 2020

Предполагая, что у вас нет странных имен файлов:

find . \! -name '.' -type d -prune | 
     grep  -v -f ids.txt | 
     xargs echo rm -rf 

Это должно работать с любым POSIX find / grep / xargs . Удалите echo, когда вы будете удовлетворены, удалите -v, чтобы удалить соответствующие каталоги.

  • find - поиск файлов
    • \! -name '.' - файл не называется «.», поэтому он не включает каталог root (вам может потребоваться адаптировать его, если вы запускаете его из другого каталога)
    • -type d - выбрать только каталоги
    • -prune - после обнаружения не вводите каталог, просто напечатайте его
  • grep - фильтр
    • -f ids.txt - загрузить шаблоны из файла ids.txt
    • -v - вернуть строки, которые не совпадают
  • xargs - запустить команду с аргументами из стандартного ввода

Примечание: если вы запустите find из другого каталога, вам нужно будет изменить -name, чтобы он соответствовал базовому каталогу, в котором находятся ваши каталоги. Пример:

$ find ./60476598/ \! -name '.' -type d -prune
./60476598/
$ find ./60476598/ \! -name '60476598' -type d -prune
./60476598/chain_asd123
./60476598/hello?_1effaj
$ find /home/sorin/tmp/60476598/ \! -name '60476598' -type d -prune
/home/sorin/tmp/60476598/chain_asd123
/home/sorin/tmp/60476598/hello?_1effaj

В этом случае моя тестовая установка находится в каталоге с именем 60476598 (идентификатор вопроса). Если вы не примете это во внимание, вы увидите, что он вернет только базовый каталог, но если вы измените -name '.' на -name '60476598', он будет работать как положено. Вы должны использовать только имя каталога, а не весь путь.

Несколько лучший подход , если у вас есть набор утилит, поддерживающих разделение записей на ноль:

find . \! -name '.' -type d -prune -print0 | 
     grep -v -z -f ids.txt | 
     xargs --null echo rm -rf

В этом случае -print0 указывает find выводить результаты, разделенные нулевым символом, -z сообщает grep, что строки разделяются нулевым символом, а --null сообщает xargs что входные строки разделены нулем. Эти параметры не требуются для совместимости с POSIX, однако они доступны для вариантов этих инструментов GNU.

В чем разница?

Предположим, у вас есть каталог с Новая строка в ее имени:

ls -1la
total 28
drwxr-xr-x  6 sorin pi 4096 Mar  1 18:18 .
drwxr-xr-x 31 sorin pi 4096 Mar  1 17:26 ..
drwxr-xr-x  2 sorin pi 4096 Mar  1 17:26 chain_asd123
drwxr-xr-x  2 sorin pi 4096 Mar  1 17:26 hello_1afadf
drwxr-xr-x  2 sorin pi 4096 Mar  1 18:18 hello_1effaj
drwxr-xr-x  2 sorin pi 4096 Mar  1 18:17 hello?_1effaj
-rw-r--r--  1 sorin pi   29 Mar  1 17:28 ids.txt

В этом случае привет? _1effaj имеет новую строку, встроенную в имя.

Для первой команды вывод будет:

$ find . \! -name '.' -type d -prune | grep  -f ids.txt | xargs echo rm -rf
rm -rf _1effaj ./hello_1effaj

(он попытается удалить каталог с именем _1effaj, но hello?_1effaj будет не тронут)

$ find . \! -name '.' -type d -prune -print0 | grep  -z -f ids.txt | xargs --null echo rm -rf
rm -rf ./hello
_1effaj ./hello_1effaj

Это успешно удалит каталог hello?_1effaj.

Как мне проверить, есть ли у меня такое имя файла? :

find -name '*
*'

это должно работать в любой оболочке POSIX.

Или в bash вы можете использовать: find -name \*$'\n'\*

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