xargs
ожидает очень особый формат ввода, в котором аргументы разделяются пробелами или символами новой строки (иногда другими формами вертикального пробела, иногда зависящими от текущей локали), и где одинарные кавычки, двойные кавычки и обратный слеш могут использоваться для их экранирования (но в другом путь из кавычек оболочки).
-l1
не для передачи одной строки ввода в качестве единственного аргумента mkdir
, а для вызова одного mkdir
вызова для каждой отдельной строки ввода, но со словами в этой строке, которые по-прежнему выделяются в качестве различных аргументов mkdir
.
Реализация GNU xargs
добавила -0
возможность десятилетия назад принимать входные данные, разделенные NUL. Это наиболее очевидный способ отделить слова, которые в конечном итоге станут аргументами команды, потому что символ NUL оказывается единственным символом, который не может встречаться в аргументе команды или имени файла (выбранный формат списка, в котором по одному файлу в строке не может представлять все возможные имена файлов, так как не допускает новую строку в имени файла).
Это -0
было скопировано несколькими другими xargs
реализациями, но не всеми.
С тем, что вы можете сделать:
<file tr '\n' '\0' | xargs -0 mkdir -p --
Это будет вызывать mkdir
как можно меньше раз с максимально возможным количеством аргументов.
Но обратите внимание, что если file
он пуст, mkdir
он все равно будет запущен, и вы получите синтаксическую ошибку mkdir
из-за отсутствующего аргумента. GNU xargs
добавил -r
опцию для того, что было скопировано несколькими другими реализациями.
GNU xargs
также добавил (позже) -d
возможность указывать произвольные разделители, но я не думаю, что какая-либо другая реализация скопировала его. С GNU xargs
лучший способ:
xargs -rd '\n' -a file mkdir -p --
Передавая файл с -a
(также расширением GNU) вместо stdin, это означает, что mkdir
stdin сохраняется.
POSIXly, вам нужно будет постобработать ввод, чтобы поместить его в ожидаемый формат xargs
. Вы можете сделать это, например, с:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' | xargs mkdir -p --
Где мы заключаем каждую строку в двойные кавычки и экранируем каждую, "
как "\""
перед передачей в xargs.
Но остерегайтесь возможных ограничений:
- ошибка, когда файл пуст уже упомянутый выше
- может произойти сбой в некоторых реализациях (включая of
sed
), если содержимое file
не является допустимым текстом в текущей локали. Если file
имена файлов кодируются более чем в одной другой кодировке, или кодировка, отличная от локали, вы можете исправить локаль на C, что должно помочь.
- некоторые
xargs
реализации имеют смехотворно низкие ограничения на максимальную длину аргумента (может быть до 255 байт).
Чтобы обойти синтаксическую ошибку при пустой ошибке ввода , вы можете написать:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' |
xargs sh -c '[ "$#" -eq 0 ] || exec mkdir -p -- "$@"' sh
-d
варианта.