Xargs и комната с *

Необходимо записать цикл для парсинга параметров. Действительно можно использовать getopts команда, чтобы сделать это легко.

Это - простой пример от getopts страница руководства:

aflag=
bflag=
while getopts ab: name
do
    case $name in
    a)    aflag=1;;
    b)    bflag=1
          bval="$OPTARG";;
    ?)    printf "Usage: %s: [-a] [-b value] args\n" $0
          exit 2;;
    esac
done
if [ ! -z "$aflag" ]; then
    printf "Option -a specified\n"
fi
if [ ! -z "$bflag" ]; then
    printf 'Option -b "%s" specified\n' "$bval"
fi
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"
4
30.12.2010, 17:42
4 ответа

Что относительно rm -r a*/*? Это должно решить Вашу проблему.

7
27.01.2020, 20:47
  • 1
    , я думал ls -d a* был заполнитель для чего-то более сложного - но я не должен был принимать это. –  RedGrittyBrick 30.12.2010, 17:27
  • 2
    на самом деле, это был заполнитель, но это добилось цели –  Lombo 30.12.2010, 17:40

Команды как rm полагайтесь на оболочку для расширения подстановочных знаков, таким образом, необходимо было бы вызвать оболочку где-нибудь.

Возможно,

 ls -d a* | xargs -i sh -c sudo rm -rf {}/*
5
27.01.2020, 20:47

(Предупреждение: Я не протестировал ни одной из этих команд. Могут быть опечатки или ошибки. Попробуйте все echo или ls и нет sudo сначала.)

Общие рекомендации: xargs редко самый простой способ сделать что-то. Без -i (который удерживается от использования между прочим, используйте портативное устройство -I {} вместо этого), xargs ожидает формат ввода, который не производит никакой стандартный или общий инструмент. С -I, xargs действительно имеет некоторое использование, хотя, если Вы передаете по каналу find в него, find -exec более просто.

Вам нужна оболочка для расширения {}/*, и та оболочка должна действовать после {} был заменен одним фактическим путем. Простое решение состоит в том, чтобы сделать линию за линией обработку в оболочке. Отметьте использование трех шаблонов для получения всех файлов в каталоге как * опускает точечные файлы; не имеет значения, если некоторые шаблоны не соответствуют никакому файлу, как rm -f игнорирует любой аргумент, который не ссылается на существующий файл.

… |
while read -r line; do
  sudo rm -rf -- "$line"/* "$line"/.[!.]* "$line"/..?*
done

Xargs бесполезен здесь, так как необходимо обработать файлы один за другим так или иначе в какой-то момент, чтобы заставить оболочку выполнять globbing. Поскольку общая техника может быть полезной однако, вот способ подать имена файлов назад в оболочку от xargs. _ $0 аргумент оболочке (этому не придется там частично потрудиться придерживаться $0 назад на любой последующий аргумент, и гарантировать, что все работает даже если $1 начинается с a - и так иначе рассматривался бы как опцию к оболочке). Здесь существует два подхода: или имейте цикл оболочки по его аргументам или скажите xargs передавать отдельный аргумент каждому вызову оболочки.

… | xargs -I {} sudo sh -c 'for x; do rm -rf -- "$x"/* "$x"/.[!.]* "$x"/..?*; done' _ {}
… | xargs -I {} -n 1 sudo sh -c 'rm -rf -- "$1"/* "$1"/.[!.]* "$1"/..?*' _ {}

Я принимаю это ls -d a* игрушечный пример и что у Вас есть более сложная команда, которая производит одно имя файла на строку. Отметьте это ls -d a* не работал бы там, как большинство ls реализации не производят непечатаемые символы прозрачно. Если команда находки, использовать -exec, как в

find a* -exec sh -c 'rm -rf -- "$1"/* "$1"/.[!.]* "$1"/..?*' _ {} \; -prune
1
27.01.2020, 20:47

Другая опция состоит в том, чтобы использовать цикл оболочки вместо того, чтобы вызвать xargs вообще.

НАПРИМЕР.

ls -d a* | while read dir; do sudo rm -rf "$dir"/*; done;

Главным образом ради примера, можно также объединить эти два метода путем помещения конструкции оболочки посреди конвейера:

ls -d a* | while read dir; do ls -d "$dir"/*; done | xargs -d \\n rm -rf

-d опция к xargs просто указывает, что разделитель между аргументами является новой строкой, которая избегает потенциально катастрофических проблем с именами файлов, которые содержат пробелы (например, deadly / file)

0
27.01.2020, 20:47

Теги

Похожие вопросы