Как заставить xargs обрабатывать пробелы и специальные символы из cat?

Бенчмарк rsync. Если ничего не получилось, попробуйте:

find /dirA -mtime $whatever -print |
  xargs tar -cpf - |
  { cd /dirB && tar -xvf -; }
9
20.01.2016, 15:31
2 ответа

Puedes hacer esto POSIBLEMENTE con la opción -I:

xargs -I % mkdir % < file

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/xargs.html

1
27.01.2020, 20:04

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 )вместо стандартного ввода означает, что стандартный ввод mkdirсохраняется.

В соответствии с POSIX вам нужно отправить -обработку ввода, чтобы привести его в формат, ожидаемый xargs. Вы можете сделать это, например, с помощью:

<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' | xargs mkdir -p --

Где мы заключаем каждую строку в двойные кавычки и экранируем "как "\""перед передачей в xargs.

Но остерегайтесь возможных ограничений:

  • уже упомянутая выше ошибка при пустом файле
  • может произойти сбой в некоторых реализациях (, включая sed), если содержимое fileне является допустимым текстом в текущей локали. Если fileсодержит кодировку имен файлов в более чем одной другой кодировке или кодировке, отличной от локали, вы можете исправить локаль на C, что должно помочь.
  • некоторые xargsреализации имеют смехотворно низкие ограничения на максимальную длину аргумента (могут составлять всего 255 байт ).

Чтобы обойти синтаксическую ошибку при ошибке пустого ввода , вы можете написать:

<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' |
  xargs sh -c '[ "$#" -eq 0 ] || exec mkdir -p -- "$@"' sh
3
27.01.2020, 20:04

Теги

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