Необходимо записать цикл для парсинга параметров. Действительно можно использовать 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" "$*"
Команды как rm
полагайтесь на оболочку для расширения подстановочных знаков, таким образом, необходимо было бы вызвать оболочку где-нибудь.
Возможно,
ls -d a* | xargs -i sh -c sudo rm -rf {}/*
(Предупреждение: Я не протестировал ни одной из этих команд. Могут быть опечатки или ошибки. Попробуйте все 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
Другая опция состоит в том, чтобы использовать цикл оболочки вместо того, чтобы вызвать 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
)
ls -d a*
был заполнитель для чего-то более сложного - но я не должен был принимать это. – RedGrittyBrick 30.12.2010, 17:27