Si está utilizando xargs -0 , debe coincidir con find -0
itsbruce el
1
@ MichaelKjörling, sin comillas {} no hay diferencia. {} se expande por find, no por el shell. Una mejora sería no usar el echoque expande secuencias de escape como \b(al menos las Unix conforme echo).
Stéphane Chazelas
1
@sch ¿Estás seguro? La página de findmanual se muestra find . -type f -exec file '{}' \;en la EXAMPLESsección. Tal vez algunas conchas tratarán los frenos especialmente.
QuasarDonkey
1
Las cotizaciones no perjudican pero no hacen diferencia. Todos '{}', \{\}, {}, "{}", '{'}se expanden por el shell (lo Bourne-como la cáscara) para un argumento para encontrar que son los dos caracteres "{" y "}". Reemplace "buscar" con "buscar eco", o printf '<%s>\n' findsi desea verificar dos veces.
Pero tenga en cuenta que los espacios no son el único problema en el código que proporcionó. los caracteres de tabulación, nueva línea y comodín también son un problema.
Con
IFS='
'set-f
for i in $(find .-name '*.jpg');do echo "$i";done
Entonces solo los caracteres de nueva línea son un problema.
Lo que ha mencionado es uno de los problemas básicos que enfrentan las personas cuando intentan leer los nombres de los archivos. A veces, las personas con conocimientos limitados y que tienen una idea errónea de la estructura de archivos y carpetas tienden a olvidar que " en UNIX Todo es un archivo ". Por lo tanto, no entienden que también necesitan manejar espacios, ya que el nombre del archivo puede consistir en 2 o más palabras con espacios.
Solución: Entonces, una de las formas más conocidas de hacer esto es hacer una lectura limpia .
Aquí leeremos todos los archivos presentes y los mantendremos en una variable, la próxima vez que realicemos el procesamiento deseado solo tendremos que mantener esa variable entre comillas, lo que preservará los nombres de los archivos con espacios. Esta es una de las formas básicas de hacerlo, sin embargo, las otras respuestas proporcionadas por las otras personas aquí funcionan igual de bien.
Aquí estoy leyendo los archivos dándoles la ruta y, lo que sea que esté leyendo, los mantengo dentro de una variable I, que citaré en un momento posterior mientras lo proceso para preservar los espacios para procesarlo correctamente.
"todo es un archivo" se refiere a otra cosa. Su solución es específica de GUN y no hace frente a la barra invertida o los caracteres de nueva línea en los nombres de archivo. Los bucles "en lectura" en shells (IMO) son a menudo una indicación de una mala práctica de scripting de shell.
Stéphane Chazelas
@sch: eh, y solía pensar, está bien. Gracias por señalarlo. Probablemente necesito verlo más.
The Dark Knight
lo siento, quise decir "GNU", no "PISTOLA" arriba (es la primera vez que me doy cuenta de que son anagramas, por cierto ...)
Stéphane Chazelas
1
Simplemente con findy bash:
find .-name '*.jpg'-exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
'--{} \;
De esta manera, usamos $1en bash, como en un script básico, que abre buenas perspectivas para realizar cualquier tarea avanzada (o no).
Una forma más eficiente (para evitar tener que iniciar un nuevo bash para cada archivo):
find .-name '*.jpg'-exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done'--{}+
Mientras que las obras en zsh (donde la característica se originó a partir) y con ksh93 (con set -G), que no se debe utilizar en bash como la versión de bash se divide fundamentalmente (como GNU grep -r) a medida que desciende en enlaces simbólicos a directorios (equivalente a find -Lo del zsh ***/*.jpg) También tenga en cuenta que, al contrario de encontrar, omitirá los archivos de puntos y no descenderá a los dotdirs (por defecto).
$i
? Hago eso y funciona bien. ¿Hay algo malo con ese enfoque?Respuestas:
La forma canónica es hacer
(reemplazar
\;
con+
para pasar más de un archivo a laecho
vez)o (específico de GNU, aunque ahora algunos BSD también lo tienen):
zsh:
fuente
echo
que expande secuencias de escape como\b
(al menos las Unix conformeecho
).find
manual se muestrafind . -type f -exec file '{}' \;
en laEXAMPLES
sección. Tal vez algunas conchas tratarán los frenos especialmente.'{}'
,\{\}
,{}
,"{}"
,'{'}
se expanden por el shell (lo Bourne-como la cáscara) para un argumento para encontrar que son los dos caracteres "{" y "}". Reemplace "buscar" con "buscar eco", oprintf '<%s>\n' find
si desea verificar dos veces.Ya se han dado mejores respuestas.
Pero tenga en cuenta que los espacios no son el único problema en el código que proporcionó. los caracteres de tabulación, nueva línea y comodín también son un problema.
Con
Entonces solo los caracteres de nueva línea son un problema.
fuente
Lo que ha mencionado es uno de los problemas básicos que enfrentan las personas cuando intentan leer los nombres de los archivos. A veces, las personas con conocimientos limitados y que tienen una idea errónea de la estructura de archivos y carpetas tienden a olvidar que " en UNIX Todo es un archivo ". Por lo tanto, no entienden que también necesitan manejar espacios, ya que el nombre del archivo puede consistir en 2 o más palabras con espacios.
Solución: Entonces, una de las formas más conocidas de hacer esto es hacer una lectura limpia .
Aquí leeremos todos los archivos presentes y los mantendremos en una variable, la próxima vez que realicemos el procesamiento deseado solo tendremos que mantener esa variable entre comillas, lo que preservará los nombres de los archivos con espacios. Esta es una de las formas básicas de hacerlo, sin embargo, las otras respuestas proporcionadas por las otras personas aquí funcionan igual de bien.
SCRIPT:
Aquí estoy leyendo los archivos dándoles la ruta y, lo que sea que esté leyendo, los mantengo dentro de una variable I, que citaré en un momento posterior mientras lo proceso para preservar los espacios para procesarlo correctamente.
Espero que esto te ayude de alguna manera.
fuente
Simplemente con
find
ybash
:De esta manera, usamos
$1
en bash, como en un script básico, que abre buenas perspectivas para realizar cualquier tarea avanzada (o no).Una forma más eficiente (para evitar tener que iniciar un nuevo bash para cada archivo):
fuente
En la versión reciente de bash, puede usar la
globstar
opción:Para acciones simples, incluso puede omitir el bucle por completo:
fuente
set -G
), que no se debe utilizar en bash como la versión de bash se divide fundamentalmente (como GNUgrep -r
) a medida que desciende en enlaces simbólicos a directorios (equivalente afind -L
o del zsh***/*.jpg
) También tenga en cuenta que, al contrario de encontrar, omitirá los archivos de puntos y no descenderá a los dotdirs (por defecto).