Cómo usar el comando xargs en Linux

¿Necesitas encadenar algunos comandos de Linux juntos, pero uno de ellos no acepta la entrada con tubería? xargs puede tomar la salida de un comando y enviarla a otro comando como parámetros.

Todas las utilidades estándar de Linux tienen tres secuencias de datos asociados con ellas.

Son la secuencia de entrada estándar (stdin), la secuencia de salida estándar (stdout) y la secuencia de error estándar (stderr).

Estas secuencias funcionan con texto. Enviamos la entrada (stdin) a un comando usando texto, y la respuesta (stdout) se escribe en la ventana de la terminal como texto.

Los mensajes de error también se escriben en la ventana de la terminal como texto (stderr).

Una de las grandes características de los sistemas operativos tipo Linux y Unix es la capacidad de usar tuberías para la salida stdout de un comando a la entrada stdin de un segundo comando.

Al primer comando no le importa que tu salida no vaya a una ventana de la terminal, y al segundo comando no le importa que tu entrada no provenga de un teclado.

Aunque todos los comandos de Linux tienen las tres secuencias estándar, no todos aceptan la salida estándar de otro comando como entrada a su entrada estándar.

Eso significa que no puedes usar tuberías en la entrada a ellos.

xargs es un comando para construir tuberías de ejecución utilizando las secuencias de datos estándar. Mediante el uso de xargs se pueden hacer que comandos tales como echo, rm y mkdir acepten la entrada estándar como argumentos.

Comando xargs

xargs también acepta tuberías. También puede aceptar entradas de un archivo. xargs usa esa entrada como parámetros para los comandos con los que le hemos dicho que trabaje.

Si no le indicamos a xargs que trabaje con un comando específico, se usará de manera predeterminada echo.

Podemos usar eso para demostrar cómo xargs siempre generará una sola línea de salida, incluso a partir de entradas de varias líneas.

Si usamos la opción -1 (enumerar un archivo por línea) con ls, obtenemos una sola columna de nombres de archivo.

Esto enumera los archivos de script de shell en el directorio actual.

Obtenemos una sola columna como se esperaba. Si usamos tuberías con xargs ¿Qué obtenemos?

La salida se escribe en la ventana de la terminal, como una larga secuencia de texto.

Es esta capacidad de xargs que alimenta los parámetros a otros comandos.

Usando xargs con wc

Podemos usar xargs para que wc cuente fácilmente las palabras, caracteres y líneas en varios archivos.

Esto es lo que pasa:

  • ls enumera los archivos *.page y pasa la lista a xargs.
  • xargs pasa los nombres de archivo a wc.
  • wc trata los nombres de archivo como si los hubiera recibido como parámetros de línea de comandos.

Las estadísticas para cada archivo se muestran junto con un total general.

Usar xargs con confirmación

Podemos usar la opción –p (interactiva) para que xargs solicite la confirmación de que estamos contentos de que continúe.

Si se pasa una cadena de nombres de archivos a touch a través de xargs, touch creará los archivos para nosotros.

El comando que se ejecutará se muestra y xargs espera a que respondamos escribiendo “y” o “Y“, o “n” o “N“, y presionando Enter.

Si solo presionas Enter, se asume como “n“. El comando solo se ejecuta si escribes “y” o “Y“.

Presionamos “y” y presionamos Enter. Podemos usar ls para verificar que los archivos hayan sido creados.

Usar xargs con múltiples comandos

Podemos usar múltiples comandos con xargs usando la opción -I (argumentos iniciales).

Esta opción define una “cadena de reemplazo“. Dondequiera que aparezca el token para la cadena de reemplazo en la línea de comandos, xargs inserta los valores que se proporcionaron.

Usemos el comando tree para ver los subdirectorios del directorio actual. La opción –d (directorio) hace que tree ignore los archivos y solo reporte en los directorios.

Hay un solo subdirectorio llamado “images”.

En un archivo llamado “directories.txt”, tenemos los nombres de algunos directorios que deseamos haber creado. Podemos ver sus contenidos usando cat.

Vamos a usar esto como datos de entrada para xargs. El comando al que vamos es este:

Este se desglosa así:

  • cat directories.txt |: Esto envía el contenido del archivo directories.txt (todos los nuevos nombres de directorio) a xargs.
  • xargs -I%: Esto define una “cadena de reemplazo” con el token “%”.
  • sh -c: Esto inicia una nueva subshell. El (comando) –c le dice a lashell que lea los comandos desde la línea de comandos.
  • ‘echo %; mkdir %’: cada uno de los tokens “%” será reemplazado por los nombres de directorio que pasan a xargs. El comando echo imprimirá el nombre del directorio; El comando mkdir creará el directorio.

Los directorios se enumeran uno por uno.

Podemos usar tree una vez más para verificar que se hayan creado los directorios.

Copiar archivos a múltiples ubicaciones

Podemos usar xargs para permitirnos copiar archivos a múltiples ubicaciones con un solo comando.

Vamos a usar las tuberías con los nombres de dos directorios xargs como parámetros de entrada.

Le diremos a xargs que solo pase uno de estos parámetros a la vez al comando con el que está trabajando.

En este caso, el comando es cp. Por lo tanto, el efecto es llamar cp dos veces, cada vez con uno de los dos directorios como parámetro de línea de comandos.

El parámetro xargs que permite que esto suceda es la opción –n (número máximo). Vamos a configurar esto para que sea uno.

También estamos usando la opción –v (detallada) con cp para que informe lo que está sucediendo.

Los archivos se copian en los dos directorios, un directorio a la vez. cp informa cada acción de copia de archivo para que podamos ver cómo se lleva a cabo.

Eliminar archivos en directorios anidados

Si los nombres de archivo tienen espacios y caracteres extraños, como los caracteres de nueva línea, xargs no podrá interpretarlos correctamente.

Podemos superar ese problema utilizando la opción -0 (delimitador nulo). Esto le indica a xargs que use el carácter nulo como delimitador final para los nombres de archivo.

Vamos a usar find en este ejemplo. find tiene su propia opción para tratar con espacios en blanco y caracteres extraños en los nombres de archivo. Esta es la opción -print0 (nombre completo, caracter nulo).

Esto se descompone así:

  • find . -name “*.png”: find buscará en el directorio actual “.” objetos con nombres que coincidan con “*.png” que sean archivos (type -f).
  • -print0: los nombres serán terminados por un caracter nulo, y los espacios y caracteres extraños serán atendidos.
  • xargs -0xargs también considerará que los nombres de archivo están terminados en nulo, y los espacios y caracteres extraños no causarán problemas.
  • rm -v -rf “{}”: rm será detallado e informará lo que está sucediendo (-v). Será recursivo (-r) y examinará subdirectorios anidados, y eliminará archivos sin preguntar (-f). El “{}” se reemplaza por cada nombre de archivo.

Se buscan todos los subdirectorios y se eliminan los archivos que coinciden con el patrón de búsqueda.

Eliminar directorios anidados

Digamos que queremos eliminar un conjunto de subdirectorios anidados. tree nos dejará verlos.

Este comando usará find para buscar recursivamente dentro del directorio actual. El objetivo de búsqueda es un directorio llamado “level_one”. Los nombres de directorio se pasan por medio de xargsrm.

Los únicos cambios significativos entre este comando y el comando anterior son, el término de búsqueda es el nombre del directorio superior y -type d le dice a find que busque directorios, no archivos.

El nombre de cada directorio se imprime a medida que se elimina. Podemos consultarlo con tree:

Todos los subdirectorios anidados se eliminaron.

Eliminar todos los archivos, excepto un tipo de archivo

Podemos usar find, xargs y rm para eliminar todos los archivos, aparte de un tipo que queremos conservar.

Es un poco contradictorio, pero proporcionamos el nombre del tipo de archivo que deseamos conservar, no el nombre de los que queremos eliminar.

La opción –not le indica a find que devuelva los nombres de los archivos que no coinciden con el patrón de búsqueda.

Estamos usando la opción -I (argumentos iniciales) con xargs una vez más. Esta vez, el token de reemplazo de cadena que estamos definiendo es “{}”.

Esto se comportará exactamente igual que el token de reemplazo de cadena que generamos anteriormente, que resultó ser un “%”.

Podemos consultar con ls. Los únicos archivos que quedan en el directorio son los que coinciden con el patrón de búsqueda “*.sh“.

Crear un archivo de almacenamiento con xargs

Podemos usar find para buscar archivos y pasarlos a través de xargs a tar, para crear un archivo de almacenamiento.

Vamos a buscar en el directorio actual. El patrón de búsqueda es “*.page“, por lo que buscaremos archivos “.page“.

Los archivos se enumeran como se esperaba, a medida que se crea el archivo.

El mediador de datos

A veces necesitas un poco de andamio cuando apilas cosas. Xargs cierra la brecha entre los comandos que pueden pasar información y los comandos que no están diseñados para incorporarla.

Ambos, xargs y find tienen una gran cantidad de opciones.

Te recomendamos que consultes sus páginas de manual para obtener más información.