GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo analizo la salida del comando de búsqueda cuando los nombres de archivo tienen espacios en ellos?

Idealmente, no lo haga de esa manera, porque analizar correctamente los nombres de los archivos en un script de shell siempre es difícil (arréglelo para los espacios, aún tendrá problemas con otros caracteres incrustados, en particular, la nueva línea). Esto incluso aparece como la primera entrada en la página BashPitfalls.

Dicho esto, hay una manera de casi hacer lo que quieres:

oIFS=$IFS
IFS=$'\n'

find . -name '*.txt' | while read -r i; do
  # use "$i" with whatever you're doing
done

IFS=$oIFS

Recuerde citar también $i al usarlo, para evitar que otras cosas interpreten los espacios después. También recuerde configurar $IFS volver después de usarlo, porque no hacerlo causará errores desconcertantes más tarde.

Esto tiene otra advertencia adjunta:lo que sucede dentro del while loop puede tener lugar en una subcapa, según la capa exacta que esté utilizando, por lo que es posible que la configuración de las variables no persista. El for la versión en bucle evita eso, pero al precio de eso, incluso si aplica el $IFS solución para evitar problemas con los espacios, tendrá problemas si el find devuelve demasiados archivos.

En algún momento, la solución correcta para todo esto es hacerlo en un lenguaje como Perl o Python en lugar de Shell.


Usa find -print0 y canalícelo a xargs -0 , o escribe tu propio pequeño programa en C y canalízalo a tu pequeño programa en C. Esto es lo que -print0 y -0 fueron inventados para.

Los scripts de shell no son la mejor manera de manejar nombres de archivo con espacios:puede hacerlo, pero se vuelve torpe.


Puede configurar el "separador de campo interno" (IFS ) a algo más que espacio para la división del argumento del bucle, por ejemplo,

ORIGIFS=${IFS}
NL='
'
IFS=${NL}
for i in $(find . -name '*.txt'); do
    IFS=${ORIGIFS}
    #do stuff
done
IFS=${ORIGIFS}

Restablecí IFS después de su uso en find, sobre todo porque se ve bien, creo. No he visto ningún problema al configurarlo en nueva línea, pero creo que esto es "más limpio".

Otro método, dependiendo de lo que quieras hacer con la salida de find , es usar directamente -exec con el find comando, o use -print0 y canalícelo en xargs -0 . En el primer caso find se encarga de que el nombre del archivo se escape. En el -print0 caso, find imprime su salida con un separador nulo y luego xargs se divide en esto. Dado que ningún nombre de archivo puede contener ese carácter (que yo sepa), esto también es siempre seguro. Esto es principalmente útil en casos simples; y por lo general no es un gran sustituto para un for completo bucle.


Linux
  1. ¿Cómo asignar la salida de un comando a una variable de shell?

  2. ¿Cómo detener el comando Buscar después de la primera coincidencia?

  3. ¿Cómo saber en qué versión de Os X estoy desde la línea de comandos?

  4. ¿Cómo se especifican los nombres de archivo dentro de un zip al crearlo en la línea de comando desde una tubería?

  5. ¿Cómo agregar la salida a un archivo?

Cómo encontrar archivos en Linux con el comando Buscar

Cómo averiguar qué hace un comando de Linux

Cómo cambiar el color de salida de 'Echo' en Linux

Cómo encontrar archivos con el comando fd en Linux

Cómo encontrar la utilización de la CPU, qué hace que el sistema se cuelgue

¿Cuál es la sintaxis correcta de find -exec?