команда rm, которая будет использоваться с xargs, чтобы исключить некоторые папки, имеющие место в имени

В одном каталоге у меня есть около 50 файлов и папок, которые включают в себя некоторые папки с пространством в их именах. Я хочу удалить некоторые папки с помощью команды ls, grep и xargs, но не могу удалить папки с пространством в их именах и показывает исключение. Может кто-нибудь помочь? Использование ОС Solaris.
Я пытался ниже для удаления все, кроме $файлов

ls / grep-v «$files » / xargs rm

и когда я попытался ниже команды он удаляет все, включая $файлы, которые я не хочу.

ls / grep-v «$files » / xargs rm —* *

3 ответа

  1. Unix-подобные системы позволяют любым символам появляться в именах файлов, за исключением символа ASCII NUL и косой черты. Косые черты могут встречаться в именах путей (как разделитель каталогов), но не в именах фактических записей каталога. Это означает, что список файлов, которые xargsчитает, на самом деле может содержать пробелы – пробелы, вкладки и символы новой строки. Поскольку по умолчанию xargsпредполагается, что список файлов, которые он читает, использует пустое пространство в качестве разделителя аргументов, он не может правильно обрабатывать случай, когда имя файла фактически включает пустое пространство. Это делает поведение по умолчанию xargs практически бесполезен для обработки произвольных данных.

    Чтобы решить эту проблему, GNU findutils представила действие’ — print0 ‘ для find. Для разделения записей в списке файлов используется символ ASCII NUL. Это идеальный выбор разделителя, так как это единственный символ, который не может появиться в имени пути. Опция ‘ -0 ‘ xargsпозволяет предположить, что аргументы разделены ASCII NUL вместо пробела. Он также отключает другое несоответствие в поведении по умолчаниюxargs, которое заключается в том, что он обращает внимание на кавычки символов в своих входных данных. Некоторые версии xargs также завершается, когда они видят одинокое ‘_’ во входных данных, но GNU find больше не делает этого (так как это стало необязательным поведением в стандарте Unix).

    Итак, поставив find-print0 вместе с xargs -0 получаем эту команду:

    find /var/tmp/stuff -mtime +90 -print0 | xargs -0 /bin/rm
    

    Результатом является эффективный способ работы, который правильно обрабатывает все возможные символы, которые могут появиться в списке файлов для удаления. Это хорошая новость. Однако, как я уверен, вы ожидаете, есть и другие плохие новости. Проблема в том, что это не портативная конструкция; хотя другие версии Unix (особенно производные от BSD) поддерживают ‘-print0’, это не универсально.

  2. Вы не можете удалить папки с помощью rmкоманды, если не используете -rпараметр (рекурсивный). Я предполагаю, что вы хотите удалить отдельные файлы, а не целые каталоги.

    В любом случае, вы можете обрабатывать файлы и каталоги с арбитражными именами стандартными findкомандами, которые всегда доступны в Solaris. xargsНет необходимости в специальных расширениях GNU.

    Вот пример. Все файлы, кроме тех, с .формат JPG или. Java суффикс, и те, имеющие keepme в их имена будут сохранены, все оставшиеся файлы будут обработаны:

    find . -type f ! -name "*.jpg" ! -name "*keepme*" ! -name "*.java" -exec echo rm {} +
    

    Удалите echoкоманду, если вы хотите, чтобы удаление файла было выполнено.

  3. Без использования нестандартных расширений и предполагая, что ваша оболочка реализуетwhile read ..., это также должно работать:

    ls | grep -v "$files" | while read filename; do
        rm "$filename"
    done
    

    Котировки вокруг $filenameкритические. Без кавычек аргумент будет разбит на любые пробелы, которые могут быть в имени.

    Заметьте также, что не будет удалять каталог — как уже упоминалось, вам нужно rm -r— или rmdir— сделать это. Но rm -rудалит каталог и все в нем . rmdirпо умолчанию непустой каталог не удаляется.

    Вы, вероятно, должны запустить тест сначала с чем-то вроде

    ls | grep -v "$files" | while read filename; do
        ls -ld "$filename"
    done
    

    Используйте -ldпараметрыls, чтобы убедиться, что вы получаете правильный файл, а также не перечислять содержимое каталога, если переданное имя файла является каталогом.