systemadmin.es > Utilidades > Uso de xargs: Herramientas UNIX (II)

Uso de xargs: Herramientas UNIX (II)

En el momento que empezamos a tratar con directorios con una gran cantidad de archivos en el empezamos a ver como realmente funcionan las cosas y la gran utilidad de xargs. Vamos a ver unos ejemplos…

Suponiendo que tenemos en un directorio muchos archivos y queremos borrarlos, normalmente ejecutaríamos:

# rm -fr *

Esto bash lo transforma en lo siguiente y lo ejecuta:

# rm -fr file1 file2 file3 file 4 ..........

Transforma la expresión “*” en una lista de todos los ficheros que cumplen tal expresión. Evidentemente, al ser la lista tan larga no cabe en el buffer reservado al comando a ejecutar (todo tiene un límite).

Gracias a xargs podemos ejecutar el comando de la siguiente manera:

ls | xargs rm -fr

Esto lanzaría un proceso rm para cada fichero del directorio. Tenemos otras opciones disponibles que nos pueden ser útiles:

  • -t: Nos permite ver el comando antes de ejecutarlo:
    # ls | xargs -t echo
    echo ipp.txt openvpn-status.log run supervise
    ipp.txt openvpn-status.log run supervise
    
  • -n: Permite definir el número de argumentos que vemos a pasar a cada comando, por ejemplo:
    # ls | xargs -n2 echo
    ipp.txt openvpn-status.log
    run supervise
    
  • -I: Permite definir donde se van a definir los parámetros, por ejemplo:
    # ls | xargs -I ARG echo antes ARG despues
    antes ipp.txt despues
    antes openvpn-status.log despues
    antes run despues
    antes supervise despues
    
  • -P: Permite definir el número de procesos paralelos a lanzar al mismo tiempo. Mediante esta opción podemos usar xargs como un gestor de threads. Por ejemplo, si lanzamos el siguiente comando:
    # ls | xargs -I ARG -P4 -n1 sleep 4
    

    Podremos ver en la lista de procesos lo siguiente:

    root      4687  0.0  0.0  59132   540 pts/0    S    08:25   0:00                      \_ xargs -I ARG -P4 -n1 sleep 4
    root      4688  0.0  0.0  58864   508 pts/0    S    08:25   0:00                      |   \_ sleep 4
    root      4690  0.0  0.0  58864   508 pts/0    S    08:25   0:00                      |   \_ sleep 4
    root      4691  0.0  0.0  58864   508 pts/0    S    08:25   0:00                      |   \_ sleep 4
    root      4692  0.0  0.0  58864   508 pts/0    S    08:25   0:00                      |   \_ sleep 4
    

10 comments to “Uso de xargs: Herramientas UNIX (II)”

  1. Antes de nada decirte que enhorabuena por el blog y que esta muy bien 😉

    En este post dices:

    Gracias a xargs podemos ejecutar el comando de la siguiente manera:

    ls | xargs rm -fr

    Esto lanzaría un proceso rm para cada fichero del directorio. Tenemos otras opciones disponibles que nos pueden ser útiles:

    Para tener un proceso para cada fichero no sería así:

    ls | xargs -n1 rm -fr

    No hay preview así que no se como quedará esto 😉

  2. Esto lo que haría sería equivalente a:

    ls | xargs rm -fr
    

    Le estas indicando que quieres lanzar un rm con un solo parámetro.

    Suponiendo unos ficheros sería:

    rm -fr fichero1
    rm -fr fichero2
    rm -fr fichero3
    rm -fr fichero4
    ...
    

    Al usar n4 sería:

    rm -fr fichero1 fichero2 fichero3 fichero4
    rm -fr fichero5 fichero6 fichero7 fichero8
    ...
    
  3. Hola de nuevo,

    Mi duda venía por que para ver que pasa cuando ejecuto

    $ ls | xargs rm -rf

    añado la opción -t, como tu indicas, y la respuesta es:

    $ ls | xargs -t rm -rf
    rm -rf fichero1 fichero2 fichero3 fichero4 fichero5

    Gracias por responder 😉

  4. Buen día,
    Tengo un fichero plano con un registro de 6 posiciones, que es el código de artículo.
    A partir de ese fichero necesito generar uno nuevo pero en sentido inverso.
    Ejemplo:

    000001
    000002
    000003
    000004
    000005
    000006
    000007

    Y quiero generar uno nuevo con la opción -n2
    y queda asi:
    000001 000002
    000003 000004
    000005 000006
    000007 000007
    ………. ……….

    Hasta aqui todo ok. pero hoy necesite queu n archivo con 21.000 registro quede agrupado en 1000 columnas.
    Lo máximo que me generó fueron 290 columnas.
    El Xargs con la opción -n tiene limite?

    Gracias !!!

  5. No entiendo para que quieres usar xargs para hacer esto. Para realizar lo que comentas puedes usar paste:

    # seq -w 1 10 | paste - -
    01      02
    03      04
    05      06
    07      08
    09      10
    
  6. Para borrar grandes cantidades de ficheros también se puede usar la siguiente expresión:

    find . -name “*” -exec rm -rf {} \;

    Saludos

  7. Buenas,

    Un comando que suelo usar para borrar cantidades considerables de archivos, y asi evitar el error de “too many files” del rm, es:

    $ echo * | xargs -n 20 rm

    Es basico, para borrar de a 20 archivos por vez, se le pueden hacer mejoras segun el gusto del consumidor. Lo he usado en Linux, HP-UX y Solaris sin problemas.

    Saludos.

  8. Hola!
    tengo varios archivos con su contenido:
    arch1.txt1
    aaaaaaa
    bbbbbbb
    arch2.txt2
    ccccccc
    ddddddd
    quiero generar un archivo archx.txt
    aaaaaaaa1
    bbbbbbbb1
    cccccccc2
    dddddddd2
    donde el final de cada registro lo obtenga de ultima posición del nombre del archivo donde esta contenido
    gracias.

  9. no te conviene mas usar awk? o en su defecto gawk.

    en lo personal (trabajo con un SCO algo anticuado y con Linux) prefiero programar en la version antigua para tener compatibilidad con la nueva.

    (aunque siempre habra un catch, es peor programar en la nueva version y tratar que corra en la antigua).

  10. Buenas, el post es antiguo pero en mi opinión tiene algo incorrecto y es a lo que hace referencia Isaías.

    Para que xargs ejecute un comando por linea / argumento, se debe usar la opción -n o bien -l. En el artículo se invita a pensar que “-n 1” es la opción predeterminada.

    Los siguientes comandos no son idénticos.
    ls | xargs -n1 rm -fr
    ls | xargs rm -fr

    Es más, dependiendo del número de ficheros, el usar -n 1 ocasionaría un uso elevado de recursos y el comando tardaría muchísimo más ya que se ejecuta un rm por cada fichero.

    Un ejemplo.
    time $(find /home/maria -print0 | xargs -0 -t > cacas 2>&1)

    real 0m0.482s
    user 0m0.220s
    sys 0m0.220s

    awk '{ print length($0); }' cacas
    131032
    131026
    127665
    127659

    time $(find /home/maria -print0 | xargs -0 -t -n 1 > cacas 2>&1)

    real 0m37.841s
    user 0m0.670s
    sys 0m3.710s

    # Al usar -n 1, el número de lineas es 7846.
    awk '{ print length($0); }' cacas | wc -l
    7846

    Si se observan el número de lineas y el número de caracteres por cada una de ellas, se puede comprobar su funcionamiento, aunque con la opción “-t” se llega a la misma conclusión.

    Un saludo.

Deja un comentario:

XHTML - Tags permitidos:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>