Por ejemplo, ahora estoy usando lo siguiente para cambiar un par de archivos cuyas rutas de acceso de Unix escribí a un archivo:
cat file.txt | while read in; do chmod 755 "$in"; done
¿Hay una manera más elegante y segura?
Si su archivo no es demasiado grande y todos los archivos están bien nombrados (sin espacios u otros caracteres especiales como comillas), simplemente puede:
chmod 755 $(
Si tiene caracteres especiales y / o muchas líneas en file.txt
.
xargs -0 chmod 755 < <(tr \\n \\0
si su comando necesita ejecutarse exactamente 1 vez por entrada:
xargs -0 -n 1 chmod 755 < <(tr \\n \\0
Esto no es necesario para esta muestra, ya que chmod
acepta múltiples archivos como argumento, pero esto coincide con el título de la pregunta.
Para algunos casos especiales, incluso podría definir la ubicación del argumento del archivo en comandos generados por xargs
:
xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0
Sí.
while read in; do chmod 755 "$in"; done < file.txt
De esta forma puedes evitar un proceso de cat
.
cat
casi siempre es malo para un propósito como este. Puede leer más sobre el uso inútil del gato.
Si sabe que no tiene espacios en blanco en la entrada:
xargs chmod 755 < file.txt
Si puede haber espacios en blanco en las rutas, y si tiene xargs de GNU:
tr '\n' '\0' < file.txt | xargs -0 chmod 755
si tiene un buen selector (por ejemplo, todos los archivos .txt en un directorio), podría hacer lo siguiente:
for i in *.txt; do chmod 755 "$i"; done
Bash para el bucle
o una variante tuya:
while read line; do chmod 755 "$line"; done
Si desea ejecutar su comando en paralelo para cada línea, puede usar GNU Parallel
parallel -a
Cada línea de su archivo se pasará al progtwig como argumento. De forma predeterminada, el parallel
ejecuta la mayor cantidad de subprocesos que cuenten sus CPU. Pero puedes especificarlo con -j
Veo que etiquetó a bash, pero Perl también sería una buena manera de hacer esto:
perl -p -e '`chmod 755 $_`' file.txt
También puede aplicar una expresión regular para asegurarse de obtener los archivos correctos, por ejemplo, para procesar solo archivos .txt:
perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt
Para “previsualizar” lo que está sucediendo, simplemente reemplace los trazos con comillas dobles y anteponga a la print
:
perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt
También puede usar AWK que le puede dar más flexibilidad para manejar el archivo
awk '{ print "chmod 755 "$0"" | "/bin/sh"}' file.txt
si su archivo tiene un separador de campo como:
campo1, campo2, campo3
Para obtener solo el primer campo que haces
awk -F, '{ print "chmod 755 "$1"" | "/bin/sh"}' file.txt
Puede consultar más detalles sobre la documentación de GNU https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple