GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo puedo pasar todos los argumentos con xargs en medio del comando en Linux?

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 .


Linux
  1. Comando DD de Linux:15 ejemplos con todas las opciones

  2. Ordenar comando en Linux con ejemplos

  3. Cómo pasar la contraseña al comando SCP en Linux

  4. ¿Cómo puedo ejecutar un comando diferente pero con los mismos argumentos?

  5. Cómo pasar la salida del comando como varios argumentos a otro comando

Cómo configurar redes IP con el comando nmcli en Linux

Cómo usar el comando rm de Linux con ejemplos

Cómo administrar contraseñas de Linux con el comando pass

Cómo pasar la contraseña al comando SSH en Linux

Cómo usar el poderoso comando Xargs en Linux [explicado con ejemplos]

¿Cómo usar el comando xargs en Linux?