Cómo usar el comando xargs en Linux

Contenidos

Un indicador de terminal de Linux en una computadora portátil

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

Todas las utilidades estándar de Linux disponen tres flujos de datos asociado con ellos. Son el flujo de entrada estándar (stdin), el flujo de salida estándar (stdout) y el flujo de error estándar (stderr).

Estos flujos funcionan con texto. Enviamos la entrada (stdin) a un comando usando texto, y la solución (stdout) se escribe en la ventana de terminal como texto. Los mensajes de error además se escriben en la ventana del terminal como texto (stderr).

Una de las grandes características de los sistemas operativos Linux y tipo Unix es la capacidad de canalizar la salida stdout de un comando a la entrada stdin de un segundo comando. Al primer comando no le importa que su salida no vaya a una ventana de terminal, y al segundo comando no le importa que su entrada no provenga de un teclado.

Aún cuando todos los comandos de Linux disponen los tres flujos estándar, no todos aceptan la salida estándar de otro comando como entrada a su stdin. Eso significa que no puede canalizar la entrada a ellos.

xargs es un comando para construir canalizaciones de ejecución usando los flujos de datos estándar. A través de el uso xargs podemos hacer comandos como echo, rm, y mkdir aceptar entrada estándar como argumentos.

El comando xargs

xargs aceptará entrada entubada. Además puede aceptar la entrada de un archivo. xargs utiliza esa entrada como parámetros para los comandos con los que le hemos dicho que trabaje. Si no contamos xargs para trabajar con un comando específico, se utilizará por defecto echo.

Podemos utilizar eso para demostrar cómo xargs siempre generará una sola línea de salida, inclusive desde una entrada de varias líneas.

Si usamos el -1 (enumere un archivo por línea) con la opción ls, obtenemos un columna única de nombres de archivo.

ls -1 ./*.sh

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

Obtenemos una sola columna como se esperaba. Si lo canalizamos xargs que obtenemos

ls -1 ./*.sh | xargs

La salida se escribe en la ventana de terminal, como un largo flujo de texto.

Es esta capacidad la que xargs introducir parámetros en otros comandos.

Uso de xargs con wc

Nosotros podemos utilizar xargs tener facilmente wc cuenta los palabras, caracteres y líneas en varios archivos.

ls *.page | xargs wc

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 comando.

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

Utilizar xargs con confirmación

Podemos utilizar el -p opción (interactiva) para tener xargs Pídanos confirmación de que estamos felices de que proceda.

Si pasamos una cadena de nombres de archivo a touch, a través de xargs, touch voluntad crea los archivos para nosotros.

echo 'one two three' | xargs -p touch

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

Si solo presiona Enter, se trata como «n». El comando solo se ejecuta si escribe “y” o “Y”.

Pulsamos “y” y pulsamos Enter. Nosotros podemos utilizar ls para chequear que se han creado los archivos.

ls one two three

Utilizar xargs con bastantes comandos

Podemos utilizar varios comandos con xargs usando el -I (argumentos iniciales) opción.

Esta opción establece una «cadena de reemplazo». Dondequiera que aparezca el token para la cadena de reemplazo en la línea de comando, los valores que se proporcionaron a xargs se insertan.

Usemos el tree comando para ver los subdirectorios del directorio actual. los -d (directorio) opción causas tree para ignorar archivos y solo informar sobre directorios.

tree -d

Hay un único subdirectorio llamado «imágenes».

En un archivo llamado “directorios.txt”, tenemos los nombres de algunos directorios que pretendemos haber creado. Podemos mirar su contenido usando cat.

cat directories.txt

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

cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'

Esto se desglosa así:

  • cat directorios.txt |: Esto inserta el contenido del archivo directrories.txt (todos los nuevos nombres de directorio) en xargs.
  • xargs -I%: Esto establece una «cadena de reemplazo» con el token «%».
  • sh -c: Esto inicia una nueva subcapa. los -c (comando) le dice al shell que lea los comandos de la línea de comandos.
  • ‘eco %; mkdir% ‘: cada uno de los tokens «%» será reemplazado por los nombres de directorio que se pasan por xargs. los echo el comando imprimirá el nombre del directorio; los mkdir comando creará el directorio.

Los directorios se enumeran uno por uno.

Nosotros podemos utilizar tree una vez más para verificar que se hayan creado los directorios.

tree -d

Copia de archivos en varias ubicaciones

Nosotros podemos utilizar xargs para permitirnos copiar archivos a múltiples ubicaciones con un solo comando.

Vamos a canalizar los nombres de dos directorios a xargs como parámetros de entrada. Bien dicho xargs para pasar solo uno de estos parámetros al mismo tiempo al comando con el que está trabajando.

En esta circunstancia, el comando es cp. Entonces el efecto es llamar cp dos veces, cada vez con uno de los dos directorios como parámetro de línea de comandos. los xargs parámetro que posibilita que esto suceda es el -n (número máximo) opción. Vamos a configurar esto para que sea uno.

Además estamos usando el -v (detallado) opción con cp para que reporte lo que está sucediendo.

echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page

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

Quitar archivos en directorios anidados

Si los nombres de archivo disponen espacios y caracteres extraños, como caracteres de nueva línea, xargs no podrá interpretarlos correctamente. Podemos superar ese problema usando la opción -0 (terminador nulo). Esto dice xargs para usar el carácter nulo como delimitador final para los nombres de archivo.

Vamos a utilizar find en este ejemplo. find tiene su propia opción para lidiar con espacios en blanco y caracteres extraños en los nombres de archivo. Es el -print0 (nombre completo, carácter nulo).

find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"

Esto se desglosa así:

  • hallar . -nombre «* .png»: find va a buscar en el directorio actual «.» para objetos con nombres que coincidan con «* .png» que son archivos (type -f).
  • -print0: los nombres terminarán con un carácter nulo y se atenderán los espacios y caracteres extraños.
  • xargs -0: xargs además considerará que los nombres de archivo terminan 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 buscará a través de 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.

Quitar directorios anidados

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

tree -d

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"

Este comando usará find para buscar de forma recursiva dentro del directorio actual. El objetivo de la búsqueda es un directorio llamado «level_one». Los nombres de directorio se pasan xargs para rm.

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 dice find para buscar directorios, no archivos.

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

tree -d

Se eliminan todos los subdirectorios anidados.

Eliminación de todos los archivos, excepto un tipo de archivo

Nosotros podemos utilizar find, xargs y rm para borrar todos los archivos excepto un tipo que queremos conservar. Es un poco contradictorio, pero proporcionamos el nombre del tipo de archivo que pretendemos guardar, no el nombre de los que queremos borrar.

los -not la opción dice find para devolver los nombres de los archivos que no coincidir con el patrón de búsqueda. Estamos usando el -I (argumentos iniciales) opción con xargs una vez más. Esta vez, el token de cadena de reemplazo que estamos definiendo es «{}». Esto se comportará exactamente igual que el token de cadena de reemplazo que generamos previamente, que resultó ser un «%».

find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}

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

ls -l

Crear un archivo de almacenamiento con Xargs

Nosotros podemos utilizar find para buscar archivos y pasarlos xargs para 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».

find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

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

El mediador de datos

A veces necesitas un pequeño andamio cuando apilas cosas juntas. xargs cierra la brecha entre los comandos que pueden enviar información y los comandos que no están diseñados para recibirla.

Ambos xargs y find dispone de una gran cantidad de alternativas. Le sugerimos que consulte sus páginas de manual para obtener más información.

setTimeout(function(){
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version=’2.0′;
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s) } (window, document,’script’,
‘https://connect.facebook.net/en_US/fbevents.js’);
fbq(‘init’, ‘335401813750447’);
fbq(‘track’, ‘PageView’);
},3000);

Suscribite a nuestro Newsletter

No te enviaremos correo SPAM. Lo odiamos tanto como tú.