Supongamos que tengo un resultado de un comando (como ls -1
):
a
b
c
d
e
...
Quiero aplicar un comando (por ejemplo echo
) a cada uno, a su vez. P.ej
echo a
echo b
echo c
echo d
echo e
...
¿Cuál es la forma más fácil de hacer eso en bash?
Supongamos que tengo un resultado de un comando (como ls -1
):
a
b
c
d
e
...
Quiero aplicar un comando (por ejemplo echo
) a cada uno, a su vez. P.ej
echo a
echo b
echo c
echo d
echo e
...
¿Cuál es la forma más fácil de hacer eso en bash?
Respuestas:
Probablemente sea más fácil de usar xargs
. En tu caso:
ls -1 | xargs -L1 echo
La -L
bandera asegura que la entrada se lea correctamente. De la página del manual de xargs
:
-L number
Call utility for every number non-empty lines read.
A line ending with a space continues to the next non-empty line. [...]
ls
Lo hace automáticamente -1
en una tubería.
ls | xargs -L2 echo
y ls -1 | xargs -L2 echo
da dos salidas diferentes. El primero está todo en una línea.
xargs
solo puede ejecutar archivos ejecutables, no funciones de shell o comandos integrados de shell. Para el primero, la mejor solución es probablemente la que está read
en un bucle.
-L1
sirve.
Puede usar una operación de anteponer básica en cada línea:
ls -1 | while read line ; do echo $line ; done
O puede canalizar la salida a sed para operaciones más complejas:
ls -1 | sed 's/^\(.*\)$/echo \1/'
sh: cho: not found a sh: cho: not found
parece que está tomando el e
eco como un comando sed o algo así.
while
bucle. cmd1 | while read line; do cmd2 $line; done
. O while read line; do cmd2 $line; done < <(cmd1)
que no crea una subshell. Esta es la versión simplificada de su sed
comando:sed 's/.*/echo &/'
"$line"
bucle while para evitar la división de palabras.
read -r line
para evitar read
jugar con los personajes escapados. Por ejemplo , echo '"a \"nested\" quote"' | while read line; do echo "$line"; done
da "a "nested" quote"
, que ha perdido su fuga. Si lo hacemos echo '"a \"nested\" quote"' | while read -r line; do echo "$line"; done
, obtenemos "a \"nested\" quote"
lo esperado. Ver wiki.bash-hackers.org/commands/builtin/read
Puede usar un bucle for :
para archivo en *; hacer echo "$ archivo" hecho
Tenga en cuenta que si el comando en cuestión acepta múltiples argumentos, el uso de xargs es casi siempre más eficiente, ya que solo tiene que generar la utilidad en cuestión una vez en lugar de varias veces.
printf '%s\0' * | xargs -0 ...
- de lo contrario, es bastante inseguro con nombres de archivo con espacios en blanco, comillas, etc.
En realidad, puede usar sed para hacerlo, siempre que sea GNU sed.
... | sed 's/match/command \0/e'
Cómo funciona:
cat /logs/lfa/Modified.trace.log.20150904.pw | sed -r 's/^(.*)(\|006\|00032\|)(.*)$/echo "\1\2\3 - ID `shuf -i 999-14999 -n 1`"/e'
for s in `cmd`; do echo $s; done
Si cmd tiene una salida grande:
cmd | xargs -L1 echo
cmd
tiene espacios en su salida, el primero fallará.
xargs falla con barras invertidas, comillas. Tiene que ser algo como
ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."
Opción xargs -0:
-0, --null Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or backslashes. The GNU find -print0 option produces input suitable for this mode.
ls -1
termina los elementos con caracteres de nueva línea, por lo que los tr
traduce en caracteres nulos.
Este enfoque es aproximadamente 50 veces más lento que iterar manualmente con for ...
(ver la respuesta de Michael Aaron Safyan ) (3.55s vs. 0.066s). Pero para otros comandos de entrada como localizar, buscar, leer desde un archivo ( tr \\n \\0 <file
) o similar, debe trabajar de xargs
esta manera.
Mejor resultado para mí:
ls -1 | xargs -L1 -d "\n" CMD
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 command
manejará casos donde la salida de ls -1
es ambigua; use en -printf '%P\0'
lugar de -print0
si no quiere una ventaja ./
en cada uno.
ls -1
Puede ser un ejemplo aquí, pero es importante recordar que no es bueno analizar la salida dels
. Ver: mywiki.wooledge.org/ParsingLs