Použijte -I
možnost:
echo prefix | xargs -I % echo % post
Výstup:
prefix post
Toto je jeden způsob, jak to udělat
pdftk $(ls | sort -n) cat output combinewd2.pdf
nebo pomocí backtick
pdftk `ls | sort -n` cat output combinewd2.pdf
Pokud jsou například názvy souborů 100, 2, 9, 3.14, 10, 1, příkaz bude
pdftk 1 2 3.14 9 10 100 cat output combinewd2.pdf
Chcete-li zpracovávat názvy souborů s mezerami nebo jinými speciálními znaky, zvažte to opraveno verze @joeytwiddle vynikající odpověď (která neřadí číselně, viz diskuze níže):
#-- The following will handle special characters, and
# will sort filenames numerically
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./2 ./3.14 ./9 ./10 ./100
#
find . -maxdepth 1 -type f -print0 |
sort -k1.3n -z -t '\0' |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Alternativy k xargs (specifické pro bash)
xargs
je externí příkaz, v předchozím příkladu vyvolává sh
což zase vyvolá pdftk
.
Alternativou je použití vestavěného mapfile
pokud jsou k dispozici, nebo použijte poziční parametry. Následující příklady používají dvě funkce, print0_files vygeneruje názvy souborů ukončené NUL a create_pdf vyvolá pdftk
:
print0_files | create_pdf combinewd2.pdf
Funkce jsou definovány následovně
#-- Generate the NUL terminated filenames, numerically sorted
print0_files() {
find . -maxdepth 1 -type f -print0 |
sort -k1.3n -z -t '\0'
}
#-- Read NUL terminated filenames using mapfile
create_pdf() {
mapfile -d ''
pdftk "${MAPFILE[@]}" cat output "$1"
}
#-- Alternative using positional parameters
create_pdf() {
local -r pdf=$1
set --
while IFS= read -r -d '' f; do set -- "[email protected]" "$f"; done
pdftk "[email protected]" cat output "$pdf"
}
Diskuse
Jak bylo uvedeno v komentářích, jednoduchá počáteční odpověď nefunguje s názvy souborů obsahujícími mezery nebo jiné speciální znaky. Odpověď od @joeytwiddle zpracovává speciální znaky, i když neřadí číselně
#-- The following will not sort numerically due to ./ prefix,
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./10 ./100 ./2 ./3.14 ./9
#
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Neřadí se číselně, protože každý název souboru má předponu ./
podle find
příkaz. Některé verze find
podpora příkazů -printf '%P\0'
který by nezahrnoval ./
předpona. Jednodušší, přenosná oprava je přidat -d, --dictionary-order
možnost sort
příkaz, takže při porovnávání bere v úvahu pouze prázdná místa a alfanumerické znaky, ale přesto může způsobit nesprávné řazení
#-- The following will not sort numerically due to decimals
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./2 ./9 ./10 ./100 ./3.14
#
find . -maxdepth 1 -type f -print0 |
sort -dzn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Pokud názvy souborů obsahují desetinná místa, mohlo by to vést k nesprávnému číselnému řazení. sort
příkaz umožňuje posun do pole při řazení, sort -k1.3n
, musíme být opatrní při definování oddělovače polí, pokud mají být názvy souborů co nejobecnější, naštěstí sort -t '\0'
specifikuje NUL jako oddělovač polí a find -print0
volba znamená, že jako oddělovač mezi názvy souborů má být použito NUL, takže sort -z -t '\0'
určuje NUL jako oddělovač záznamu i jako oddělovač pole-- každý název souboru je pak záznamem jednoho pole. Vzhledem k tomu pak můžeme offsetovat do jediného pole a přeskočit ./
prefix zadáním 3. znaku 1. pole jako počáteční pozice pro číselné řazení, sort -k1.3n -z -t '\0'
.
To by mělo fungovat u názvů souborů obsahujících mezery, nové řádky, apostrofy a uvozovky (všechny jsou možné na souborových systémech UNIX):
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
To by mohlo být přehnané ve srovnání s přijatou odpovědí, pokud víte, že pracujete s jednoduchými názvy souborů.
Pokud ale píšete skript, který bude v budoucnu znovu použit, je žádoucí, aby jednoho dne nevybuchl, když se setká s neobvyklými (ale platnými) vstupy.
Toto je v podstatě adaptace andrewdotnovy odpovědi, která ukončuje vstupní soubory nulovým bajtem, namísto novým řádkem, takže zachovává názvy souborů, které obsahují jeden nebo více znaků nového řádku.
Příslušné možnosti -print0
, -z
a -0
sdělte každému z programů, že vstup/výstup by měl být ohraničen nulovým bytem. Tři různé programy, tři různé argumenty!
Je to ošklivé, ale můžete spustit sh -c
a přístup k seznamu argumentů předávaných xargs
jako "${@}"
, asi takhle:
ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
Další "${0}"
na konci je tam, protože jako sh
manuálová stránka říká
-c řetězec
Pokud -c je přítomna volba, pak se příkazy čtou z řetězce . Pokud jsou za řetězcem argumenty , jsou přiřazeny k pozičním parametrům počínaje $0 .
Chcete-li to otestovat, nejprve vytvořte několik souborů se složitými názvy, které naruší většinu ostatních řešení:
$ 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' "${0}"
+ 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
Všechny argumenty jsou citovány správně. Všimněte si, že toto selže, pokud některé názvy souborů obsahují nové řádky, a že ls -v
je v podstatě ls | sort -n
.