У вас есть две основные проблемы:
подключение ls *
к xargs
просто неверно. Он будет сломаться, если какое-либо из имен файлов содержит пробелы, символы новой строки, символы подстановки оболочки или (в зависимости от того, что вы используете с xargs
), если они начинаются с -
.
используйте find ... -print0 | xargs -0
вместо этого.
Вложенные цитаты. Как отмечает @Gilles в своем ответе, есть способы сделать это правильно, но очень легко потеряться и запутаться, если у вас есть несколько уровней вложенных цитат - и даже если вам это удастся, вы, вероятно, иметь код, который вы (легко) не сможете прочитать или понять завтра, не говоря уже о шести месяцах.
Намного проще просто написать сценарий, который делает то, что вы хотите, и запускать его с помощью xargs.
Если сценарий работает автономно с несколькими аргументами имени файла, он будет работать с xargs
- и без использования -I {}
(что подразумевает -L 1
Версия FreeBSD xargs
также имеет параметр -J
, который позволяет избежать этой проблемы).
Например, myscript.sh
:
#! /bin/sh
for f in "$@" ; do
echo "$f"
awk '{ print $1 }' -- "$f" | uniq
done
(большинство версий awk
, которые я пытался понять, -
означают аргументы параметра остановки обработки. original-awk
, что аналогично awk
freebsd. Если ваш awk
не работает, просто удалите его из awk
])
и запустите его как:
./myscript.sh *
Обратите внимание, что *
будет соответствовать подкаталогам, а также файлам.
или примерно так:
find . -maxdepth 1 -type f -print0 | xargs -0r /path/to/myscript.sh
или
find . -maxdepth 1 -type f -exec /path/to/myscript.sh {} +
Эти два будут обрабатывать только обычные файлы в текущем каталоге.
Если входные файлы не отсортированы, используйте sort -u
вместо uniq
.