Как я могу передать все аргументы с xargs в середине команды в linux

Я хочу передать все файлы как один аргумент в Linux, но я не могу этого сделать.

это работает

ls | sort -n | xargs  -i pdftk  {} cat output combinewd2.pdf

Это передает один аргумент для каждой команды, но я хочу, чтобы все в одной команде.

6 ответов


это один из способов сделать это

pdftk $(ls | sort -n) cat output combinewd2.pdf

или с помощью backtick

pdftk `ls | sort -n` cat output combinewd2.pdf

как указано в комментариях, это не будет работать с именами файлов, содержащими пробелы. В этом случае вы можете использовать eval

eval pdftk $(while IFS= read -r file; do
    echo \"$file\"
done < <(ls | sort -n)) cat output combinewd2.pdf

предположим, что есть два файла с именем "0 foo" и "1 bar", тогда результатом eval будет желаемая команда с именами файлов в двойных кавычках:

pdftk " 0 foo " " 1 bar " cat output combinewd2.pdf

если имена файлов могут содержать новые строки, используйте find команда, см. обсуждение @joeytwiddle в комментариях к ответу @andrewdotn. Следующее решение также обрабатывает имена файлов с двойными кавычками, используя sed команда, чтобы избежать двойных кавычек:

eval pdftk $(while IFS= read -r -d '' file; do
    echo \"$file\"
done < <(find . -maxdepth 1 -type f -print0 | \
    sed 's/"/\"/g'| sort -zn)) cat output combinewd2.pdf

использовать :

echo prefix | xargs -I % echo % post

выход:

prefix post

это некрасиво, но вы можете запустить sh -c и получить доступ к списку аргументов по xargs as "${@}", например:

ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' ""

лишние "" в конце есть, потому что, как sh man page говорит

- c строка

если - c опция присутствует, затем команды считываются из строка. Если есть аргументы после строка, они назначаются позиционным параметрам, начиная с $0.

чтобы проверить это, давайте сначала создать несколько файлов со сложными именами, которые большинство других решений:

$ seq 1 100 | xargs -I{} touch '{} with "spaces"'
$ ls
1 with "spaces"    31 with "spaces"  54 with "spaces"  77 with "spaces"
10 with "spaces"   32 with "spaces"  55 with "spaces"  78 with "spaces"
100 with "spaces"  33 with "spaces"  56 with "spaces"  79 with "spaces"
11 with "spaces"   34 with "spaces"  57 with "spaces"  8 with "spaces"
12 with "spaces"   35 with "spaces"  58 with "spaces"  80 with "spaces"
13 with "spaces"   36 with "spaces"  59 with "spaces"  81 with "spaces"
14 with "spaces"   37 with "spaces"  6 with "spaces"   82 with "spaces"
15 with "spaces"   38 with "spaces"  60 with "spaces"  83 with "spaces"
16 with "spaces"   39 with "spaces"  61 with "spaces"  84 with "spaces"
17 with "spaces"   4 with "spaces"   62 with "spaces"  85 with "spaces"
18 with "spaces"   40 with "spaces"  63 with "spaces"  86 with "spaces"
19 with "spaces"   41 with "spaces"  64 with "spaces"  87 with "spaces"
2 with "spaces"    42 with "spaces"  65 with "spaces"  88 with "spaces"
20 with "spaces"   43 with "spaces"  66 with "spaces"  89 with "spaces"
21 with "spaces"   44 with "spaces"  67 with "spaces"  9 with "spaces"
22 with "spaces"   45 with "spaces"  68 with "spaces"  90 with "spaces"
23 with "spaces"   46 with "spaces"  69 with "spaces"  91 with "spaces"
24 with "spaces"   47 with "spaces"  7 with "spaces"   92 with "spaces"
25 with "spaces"   48 with "spaces"  70 with "spaces"  93 with "spaces"
26 with "spaces"   49 with "spaces"  71 with "spaces"  94 with "spaces"
27 with "spaces"   5 with "spaces"   72 with "spaces"  95 with "spaces"
28 with "spaces"   50 with "spaces"  73 with "spaces"  96 with "spaces"
29 with "spaces"   51 with "spaces"  74 with "spaces"  97 with "spaces"
3 with "spaces"    52 with "spaces"  75 with "spaces"  98 with "spaces"
30 with "spaces"   53 with "spaces"  76 with "spaces"  99 with "spaces"
$  ls | sort -n | xargs -d'\n' sh -c 'set -x; pdftk "${@}" cat output combinewd2.pdf' ""
+ pdftk '1 with "spaces"' '2 with "spaces"' '3 with "spaces"' '4 with "spaces"' '5 with "spaces"' '6 with "spaces"' '7 with "spaces"' '8 with "spaces"' '9 with "spaces"' '10 with "spaces"' '11 with "spaces"' '12 with "spaces"' '13 with "spaces"' '14 with "spaces"' '15 with "spaces"' '16 with "spaces"' '17 with "spaces"' '18 with "spaces"' '19 with "spaces"' '20 with "spaces"' '21 with "spaces"' '22 with "spaces"' '23 with "spaces"' '24 with "spaces"' '25 with "spaces"' '26 with "spaces"' '27 with "spaces"' '28 with "spaces"' '29 with "spaces"' '30 with "spaces"' '31 with "spaces"' '32 with "spaces"' '33 with "spaces"' '34 with "spaces"' '35 with "spaces"' '36 with "spaces"' '37 with "spaces"' '38 with "spaces"' '39 with "spaces"' '40 with "spaces"' '41 with "spaces"' '42 with "spaces"' '43 with "spaces"' '44 with "spaces"' '45 with "spaces"' '46 with "spaces"' '47 with "spaces"' '48 with "spaces"' '49 with "spaces"' '50 with "spaces"' '51 with "spaces"' '52 with "spaces"' '53 with "spaces"' '54 with "spaces"' '55 with "spaces"' '56 with "spaces"' '57 with "spaces"' '58 with "spaces"' '59 with "spaces"' '60 with "spaces"' '61 with "spaces"' '62 with "spaces"' '63 with "spaces"' '64 with "spaces"' '65 with "spaces"' '66 with "spaces"' '67 with "spaces"' '68 with "spaces"' '69 with "spaces"' '70 with "spaces"' '71 with "spaces"' '72 with "spaces"' '73 with "spaces"' '74 with "spaces"' '75 with "spaces"' '76 with "spaces"' '77 with "spaces"' '78 with "spaces"' '79 with "spaces"' '80 with "spaces"' '81 with "spaces"' '82 with "spaces"' '83 with "spaces"' '84 with "spaces"' '85 with "spaces"' '86 with "spaces"' '87 with "spaces"' '88 with "spaces"' '89 with "spaces"' '90 with "spaces"' '91 with "spaces"' '92 with "spaces"' '93 with "spaces"' '94 with "spaces"' '95 with "spaces"' '96 with "spaces"' '97 with "spaces"' '98 with "spaces"' '99 with "spaces"' '100 with "spaces"' cat output combinewd2.pdf

все аргументы приведены правильно. Обратите внимание, что это не удастся, если какие-либо имена файлов содержат новые строки, и что ls -v в основном ls | sort -n.


это должно работать с именами файлов, содержащими пробелы, новые строки, апострофы и кавычки (все это возможно в файловых системах UNIX):

find . -maxdepth 1 -type f -print0 |
  sort -zn |
  xargs -0 sh -c 'pdftk "$@" cat output combinewd2.pdf' ""

это может быть излишним по сравнению с принятым ответом, если вы знаете, что работаете с простыми именами файлов.

но если вы пишете сценарий, который будет использоваться Снова в будущем, желательно, чтобы он не взорвался однажды, когда он встречает необычные (но действительные) входы.

это в основном адаптация andrewdotn's ответ, который завершает входные файлы с нулевым байтом, а не с новой строкой, следовательно, сохраняя имена файлов, которые содержат один или несколько символов новой строки.

соответствующие опции -print0, -z и -0 скажите каждой из программ, что вход / выход должен быть разделен нулевым байтом. Три разные программы, три разных аргумента!


вы можете сделать это, связав два вызова xargs. Используйте первый, чтобы связать все args вместе в одну строку и передать это как param в echo, а второй, используя -I чтобы поместить эту цепочку args в место, где вы хотите, следующим образом:

ls | sort -n | xargs echo | xargs -I {} pdftk {} cat output combinewd2.pdf

проблема здесь в том, что в то время как xargs может поместить отдельные аргументы в середине команды с -i и {}, он отказывается делать это для нескольких аргументов. Похоже, это недосмотр, который в конечном итоге вызывает у нас много проблем!

помимо решений выше, другой альтернативой является просто добавить аргументы, которые вы хотите прийти после файлов в конце списка файлов.

(
  ls | sort -n
  echo cat
  echo output
  echo combinewd2.pdf
) | xargs -d'\n' pdftk

этот подход не работает имена файлов, содержащие новые строки. Для этого редкого случая вы должны передать строки, заканчивающиеся нулевым байтом xargs, как предложено в моем другом ответе.