Usa -I
opción:
echo prefix | xargs -I % echo % post
Salida:
prefix post
Esta es una forma de hacerlo
pdftk $(ls | sort -n) cat output combinewd2.pdf
o usando acento grave
pdftk `ls | sort -n` cat output combinewd2.pdf
Por ejemplo, si los nombres de archivo son 100, 2, 9, 3.14, 10, 1, el comando será
pdftk 1 2 3.14 9 10 100 cat output combinewd2.pdf
Para manejar nombres de archivo con espacios u otros caracteres especiales, considere esto fijo versión de la excelente de @joeytwiddle respuesta (que no se ordena numéricamente, consulte la discusión a continuación):
#-- 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"
Alternativas a xargs (específicas de bash)
xargs
es un comando externo, en el ejemplo anterior invoca sh
que a su vez invoca pdftk
.
Una alternativa es usar el mapfile
incorporado si está disponible, o utilice los parámetros posicionales. Los siguientes ejemplos usan dos funciones, print0_files genera los nombres de archivo terminados en NUL y create_pdf invoca pdftk
:
print0_files | create_pdf combinewd2.pdf
Las funciones se definen de la siguiente manera
#-- 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"
}
Discusión
Como se señaló en los comentarios, la respuesta inicial simple no funciona con nombres de archivo que contienen espacios u otros caracteres especiales. La respuesta de @joeytwiddle maneja caracteres especiales, aunque no los ordena numéricamente
#-- 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"
No se ordena numéricamente debido a que cada nombre de archivo tiene el prefijo ./
por el find
dominio. Algunas versiones del find
soporte de comandos -printf '%P\0'
que no incluiría el ./
prefijo. Una solución más simple y portátil es agregar el -d, --dictionary-order
opción al sort
comando para que considere solo espacios en blanco y caracteres alfanuméricos en las comparaciones, pero aún podría producir un orden incorrecto
#-- 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"
Si los nombres de archivo contienen decimales, esto podría conducir a una clasificación numérica incorrecta. El sort
El comando permite un desplazamiento en un campo al ordenar, sort -k1.3n
, hay que tener cuidado al definir el separador de campo si los nombres de archivo van a ser lo más generales posible, afortunadamente sort -t '\0'
especifica NUL como separador de campo y find -print0
La opción indica que se utilizará NUL como delimitador entre los nombres de archivo, por lo que sort -z -t '\0'
especifica NUL como delimitador de registro y separador de campo; cada nombre de archivo es entonces un único registro de campo. Dado eso, podemos desplazarnos en el campo único y omitir el ./
prefijo especificando el tercer carácter del primer campo como la posición inicial para la ordenación numérica, sort -k1.3n -z -t '\0'
.
Esto debería funcionar en nombres de archivos que contengan espacios, líneas nuevas, apóstrofes y comillas (todos los cuales son posibles en sistemas de archivos UNIX):
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Eso podría ser excesivo en comparación con la respuesta aceptada, si sabe que está trabajando con nombres de archivo simples.
Pero si está escribiendo un script que se usará nuevamente en el futuro, es deseable que no explote un día cuando encuentre entradas inusuales (pero válidas).
Esto es básicamente una adaptación de la respuesta de andrewdotn que termina los archivos de entrada con un byte cero, en lugar de una nueva línea, por lo que conserva los nombres de archivo que contienen uno o más caracteres de nueva línea.
Las respectivas opciones -print0
, -z
y -0
decirle a cada uno de los programas que la entrada/salida debe estar delimitada por el byte cero. ¡Tres programas diferentes, tres argumentos diferentes!
Es feo, pero puedes ejecutar sh -c
y acceda a la lista de argumentos pasados por xargs
como "${@}"
, así:
ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
El "${0}"
adicional al final está ahí porque, como el sh
la página del manual dice
-c cadena
Si -c la opción está presente, luego los comandos se leen desde cadena . Si hay argumentos después de la cadena , se asignan a los parámetros posicionales, comenzando con $0 .
Para probar esto, primero creemos algunos archivos con nombres complicados que estropearán la mayoría de las otras soluciones:
$ 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
Todos los argumentos están citados correctamente. Tenga en cuenta que esto fallará si algún nombre de archivo contiene líneas nuevas y que ls -v
es básicamente ls | sort -n
.