Fatmawati Achmad Zaenuri / Shutterstock
¿Necesita encadenar algunos comandos de Linux, pero uno de ellos no acepta entrada canalizada? xargs
puede tomar el resultado de un comando y enviarlo a otro comando como parámetros.
Todas las utilidades estándar de Linux tienen tres flujos de datos asociado con ellos. Estos son el flujo de entrada estándar (stdin), el flujo de salida estándar (stdout) y el flujo de error estándar (stderr).
Estos feeds funcionan con texto. Enviamos la entrada (stdin) a un comando usando texto, y la respuesta (stdout) se escribe en la ventana de terminal como texto. Los mensajes de error también se escriben en la ventana del terminal como texto (stderr).
Una de las grandes características de los sistemas operativos Linux y 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.
Aunque todos los comandos de Linux tienen los tres flujos estándar, no todos aceptan la salida stdout de otro comando como entrada a su stdin. Esto significa que no puede enviarles entrada.
xargs
es un comando para crear canalizaciones en tiempo de ejecución utilizando flujos de datos estándar. Utilizando xargs
podemos hacer pedidos como echo
, rm
, y mkdir
aceptar entrada estándar como argumentos.
El comando xargs
xargs
aceptará la entrada canalizada. También puede aceptar la entrada de un archivo. xargs
usa esta entrada como parámetros para los comandos con los que le pedimos que trabaje. Si no decimos xargs
para trabajar con un comando específico será predeterminado echo
.
Podemos usarlo para mostrar cómo xargs
siempre generará una única fila de salida, incluso a partir de una entrada de varias líneas.
Si usamos el -1
(enumere un archivo por línea) con la opción ls
, obtenemos un una sola columna 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 hacemos pasar xargs
que obtenemos
ls -1 ./*.sh | xargs
La salida se escribe en la ventana de la terminal como un largo flujo de texto.
Es esta habilidad la que xargs
insertar parámetros en otros comandos.
Utilice xargs con wc
Nosotros podemos usar xargs
tener fácilmente wc
Cuéntalo palabras, caracteres y líneas en varios archivos.
ls *.page | xargs wc
Esto es lo que está sucediendo:
ls
enumera los archivos * .page y pasa la lista axargs
.xargs
pasar nombres de archivo awc
.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 con un total general.
Usar xargs con confirmación
Podemos usar el -p
opción (interactiva) para tener xargs
pídanos que confirmemos que estamos felices de que esto esté sucediendo.
Si pasamos una cadena de nombres de archivo a touch
, mediante xargs
, touch
voluntad crear archivos para nosotros.
echo 'one two three' | xargs -p touch
Se muestra el comando que se ejecutará y xargs
espere a 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».
Presionamos «y» y presionamos Enter. Nosotros podemos usar ls
para verificar que los archivos fueron creados.
ls one two three
Usar xargs con múltiples comandos
Podemos usar varios comandos con xargs
utilizando el -I
(argumentos iniciales).
Esta opción define una «cadena de reemplazo». Dondequiera que aparezca el token de cadena de reemplazo en la línea de comando, los valores que se proporcionaron a xargs
se insertan.
Vamos a usarlo tree
comando para mirar los subdirectorios del directorio actual. los -d
(directorio) opción causas tree
para ignorar archivos y solo informar sobre directorios.
tree -d
Solo hay un subdirectorio llamado «imágenes».
En un archivo llamado «directorios.txt», tenemos los nombres de algunos directorios que queremos crear. Podemos ver su contenido usando cat
.
cat directories.txt
Lo usaremos como datos de entrada para xargs
. El comando que vamos a utilizar es el siguiente:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
Se descompone así:
- cat directory.txt | : Esto inserta el contenido del archivo directrories.txt (todos los nombres de directorio nuevos) en
xargs
. - xargs -I%: Esto define 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 son pasados por
xargs
. losecho
el comando imprimirá el nombre del directorio; losmkdir
El comando creará el directorio.
Los directorios se enumeran uno por uno.
Nosotros podemos usar tree
una vez más para verificar que los directorios han sido creados.
tree -d
Copie archivos en varias ubicaciones
Nosotros podemos usar xargs
para permitirnos copiar archivos a múltiples ubicaciones con un solo comando.
Vamos a pipetear los nombres de dos directorios en xargs
como parámetros de entrada. Bien dicho xargs
para transmitir solo uno de estos parámetros a la vez al comando con el que está trabajando.
En este caso, 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 comando. los xargs
parámetro que permite que esto suceda es el -n
(número máximo) opción. Vamos a hacer uno.
También usamos el -v
opción (detallado) con cp
para informar de lo que está sucediendo.
echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page
Los archivos se copian en ambos directorios, un directorio a la vez. cp
marca cada acción de copia de archivo para que podamos ver cómo está sucediendo.
Eliminar archivos de directorios anidados
Si los nombres de archivo contienen espacios y caracteres extraños, como caracteres de nueva línea, xargs
no podrá interpretarlos correctamente. Podemos superar este problema utilizando la opción -0 (terminación nula). Dice xargs
para utilizar 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 administrar espacios y caracteres extraños en los nombres de los archivos. Es el -print0
(nombre completo, carácter nulo).
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Se descompone así:
- encontrar . -nombre «* .png»:
find
buscará «.» en el directorio actual para objetos cuyo nombre corresponde a «* .png» que son archivos (type -f
). - -print0: los nombres terminarán con un carácter nulo y se admitirán espacios y caracteres extraños.
- xargs -0: xargs también asumirá que los nombres de archivo terminan en un carácter nulo, y los espacios y caracteres extraños no serán un problema.
- rm -v -rf «{}»: rm será detallado e informará lo que está sucediendo (
-v
). Será recursivo (-r) e iterará a través de subdirectorios anidados y eliminará archivos sin un mensaje (-f
). El «{}» se reemplaza con 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.
tree -d
find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
Este comando usará find para realizar una búsqueda recursiva en el directorio actual. El objetivo de la búsqueda es un directorio llamado «level_one». Los nombres de directorio se transfieren 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
relata 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.
Eliminar todos los archivos excepto un tipo de archivo
Nosotros podemos usar find
, xargs
y rm
para eliminar todos los archivos excepto un tipo que queremos conservar. Es un poco contradictorio, pero proporcionamos el nombre del tipo de archivo que queremos conservar, no el nombre de los que queremos eliminar.
los -not
la opción dice find
para devolver los nombres de los archivos que no coinciden con el patrón de búsqueda. Usamos el -I
(argumentos iniciales) opción con xargs
una vez más. Esta vez, el token de cadena de reemplazo que estamos configurando es «{}». Esto se comportará exactamente igual que el token de cadena de reemplazo que generamos anteriormente, 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
Crea un archivo de almacenamiento con Xargs
Nosotros podemos usar find
para buscar archivos y transmitirlos xargs
Para tar
, para crear un archivo de almacenamiento.
Buscaremos en el directorio actual. El patrón de búsqueda es «* .page», por lo que vamos a buscar archivos «.page».
find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz
Los archivos se enumeran como se esperaba, al crear el archivo de almacenamiento.
El mediador de datos
A veces necesitas un pequeño andamio para apilar cosas juntas. xargs
cierra la brecha entre los comandos que pueden bombear información y los comandos que no están diseñados para tenerla en cuenta.
Los dos xargs
y find
tienes muchas opciones. Le recomendamos que revise sus páginas de manual para obtener más información.