xargs - Я замінюю-str різницю варіантів


16

З мого розуміння, саме таке повинно означати саме те саме:

ls -1 | xargs file {}
ls -1 | xargs -I{} file {}

якщо параметр -I не вказаний, він за замовчуванням до -I {}.

Я хочу перерахувати всі файли в поточному каталозі і запустити fileкоманду на кожному з них. Деякі мають пробіли у своїх назвах. Однак я помітив різницю. Дивіться нижче:

$ ls -1
Hello World
$ ls -1 | xargs file {}
{}:    ERROR: cannot open `{}' (No such file or directory)
Hello: ERROR: cannot open `Hello' (No such file or directory)
World: ERROR: cannot open `World' (No such file or directory)
$ ls -1 | xargs -I{} file {}
Hello World: directory

Якщо я вказано -I {}, заголовки в іменах файлів обробляються як очікується.


3
"якщо опція -I не вказана, вона за замовчуванням - -I {}" - це неправильно, принаймні, з xargs GNU.
jjlin

Я розумію свою помилку. Я повинен вказати xargs fileабо xargs -I{} file {}. Не повинно бути xargs file {}. Я думаю, коли чітко вказувати -I {}, баш буде трактувати це як file "Hello World". Без -I {} це трактується як file Hello World.
foresightyj

1
(1) Ця дискусія мало спільного з оболонкою (баш). (2) Добре, що ви знаєте -1варіант для цього ls, але він за замовчуванням увімкнено, коли на виході lsє файл або труба, тому вам тут це не потрібно. (3) Ви плутаєте -Iз застарілим -i(нижчим регістром I) варіантом. -ifooеквівалентний -Ifoo, але звичайний -iеквівалент -I{}. Але використовуйте -I{}. (4) Якщо ви дійсно хочете робити те, що ви кажете, що хочете зробити, чому б просто не сказати file *?
Скотт

@Scott Моїм початковим наміром було написати `find. -назви "* .mov" | xargs -I {} файл {} `, щоб знайти всі файли Mov рекурсивно та запустити fileїх. Але я придумав простіший приклад, використовуючи ls. Ти правий. Для цього file *найкраще.
foresightyj

1
знайти є -exec.
Крістіан Цюпіту

Відповіді:


20

-IВимагає певного заповнювач. -iВаріант буде припускати , {}є заповнювачем. Тут я знайшов припущення про {} man xargsпринаймні на Cygwin та CentOS.

xargs, що викликається без жодної опції, не потребує заповнювача, і він просто додає STDIN до кінця аргументів.

Просто додайте echoдо своїх прикладів, щоб побачити, що робить xargs:

$ ls -1
Hello World/

Ваш приклад помилки використовує {}:

$ ls -1 | xargs echo file {}
file {} Hello World/

тому filecmd бачить аргументи {} Hello Worldта помилки.

Якщо ви хочете чітко використовувати {}у своєму дзвінку xargs:

$ ls -1 | xargs -i echo file {}
file Hello World/

Або без заповнювача:

$ ls -1 | xargs echo file
file Hello World/

xargs, як називається вище, {} не потребує. Він додає STDIN до кінця команди без заповнювача. Використання {} зазвичай означає, що потрібно виконати STDIN десь посередині cmd, як у:

$ ls -1 | xargs -i mv {} /path/to/someplace/.

Це дуже зрозуміло. Хоча ваша відповідь трохи пізня, але її читання дійсно підсилює моє розуміння.
foresightyj
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.