xargs es la solución más flexible para dividir la salida en argumentos de comando.
También es muy legible por humanos y fácil de usar debido a su sencilla parametrización.
El formato es xargs -n $NUMLINES mycommand .
Por ejemplo, a echo cada línea individual en un archivo /tmp/tmp.txt harías:
cat /tmp/tmp.txt | xargs -n 1 echo
O a diff cada par sucesivo de archivos enumerados como líneas en un archivo del nombre anterior que haría:
cat /tmp/tmp.txt | xargs -n 2 diff
El -n 2 instruye xargs para consumir y pasar como argumentos separados dos líneas de lo que ha canalizado a la vez.
Puedes personalizar xargs para dividir en delimitadores además de retorno de carro/nueva línea.
Usa man xargs y google para obtener más información sobre el poder de esta utilidad versátil.
La mejor manera de hacer esto es redirigir el archivo al bucle:
# Basic idea. Keep reading for improvements.
FILE=test
while read CMD; do
echo "$CMD"
done < "$FILE"
Una redirección con < "$FILE" tiene algunas ventajas sobre cat "$FILE" | while ... . Evita un uso inútil de cat, ahorrando un proceso hijo innecesario. También evita una trampa común en la que el ciclo se ejecuta en una subcapa. En Bash, comandos en un | la tubería se ejecuta en subcapas, lo que significa que las asignaciones de variables se pierden después de que finaliza el bucle. Redirección con < no tiene ese problema, por lo que podría usar $CMD después del bucle o modificar otras variables dentro del bucle. También, de nuevo, evita procesos secundarios innecesarios.
Hay algunas mejoras adicionales que podrían realizarse:
- Agregar
IFS=por lo quereadno recortará los espacios en blanco iniciales y finales de cada línea. - Agregar
-rareadpara evitar que las barras invertidas se interpreten como secuencias de escape. - En minúsculas
CMDyFILE. La convención de Bash es que solo las variables de shell internas y ambientales están en mayúsculas. - Utilice
printfen lugar deechoque es más seguro si$cmdes una cadena como-n, queechointerpretaría como una bandera.
file=test
while IFS= read -r cmd; do
printf '%s\n' "$cmd"
done < "$file"
Lo que tienes es canalizar el texto "cat test" en el bucle.
Solo quieres:
cat test | \
while read CMD; do
echo $CMD
done