Respuesta corta (más cercana a su respuesta, pero maneja espacios)  
OIFS="$IFS" IFS=$"\n" for file in `find . -type f -name "*.csv"` do echo "file = $file" diff "$file" "/some/other/path/$file" read line done IFS="$OIFS" 
  Mejor respuesta (también maneja comodines y nuevas líneas en los nombres de archivo)  
find . -type f -name "*.csv" -print0 | while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty done 
  Mejor respuesta (basada en  Gilles » answer )  
find . -type f -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty " exec-sh {} ";" 
 O incluso mejor, para evitar ejecutar uno sh por archivo: 
find . -type f -name "*.csv" -exec sh -c " for file do echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty done " exec-sh {} + 
  Respuesta larga  
 Tiene tres problemas: 
-  De forma predeterminada, el shell divide la salida de un comando en espacios, pestañas y nuevas líneas 
 
-  Los nombres de archivo pueden contener caracteres comodín que se expandiría 
 
-  ¿Qué pasa si hay un directorio cuyo nombre termina en 
*.csv?  
  1. Dividiendo solo en líneas nuevas  
 Para averiguar en qué establecer file, el shell tiene que tomar la salida de find e interpretarlo de alguna manera; de lo contrario, file solo sería la salida completa de find . 
 El shell lee la variable IFS, que se establece en <space><tab><newline> de forma predeterminada. 
 Luego mira cada carácter en la salida de find. Tan pronto como ve un carácter que «está en IFS, cree que marca el final del nombre del archivo, por lo que establece file a los caracteres que vio hasta ahora y ejecuta el ciclo. Luego comienza donde lo dejó para obtener el siguiente nombre de archivo, y ejecuta el siguiente ciclo, etc., hasta que llega al final de la salida. 
 Así que está haciendo esto de manera efectiva: 
for file in "zquery" "-" "abc" ... 
 Para decirle que solo divida la entrada en nuevas líneas, debe hacerlo 
IFS=$"\n" 
 antes de su for ... find comando. 
 Eso establece IFS en un línea nueva única, por lo que solo se divide en líneas nuevas, y no en espacios ni tabulaciones también. 
 Si está utilizando sh o dash en lugar de ksh93, bash o zsh, debes escribir IFS=$"\n" así en su lugar: 
IFS=" " 
 Eso probablemente sea suficiente para que su script funcione, pero si está interesado en manejar otros casos de esquina correctamente, siga leyendo … 
aña  2. Expandiendo $file sin comodines  
 Dentro del bucle donde lo haces 
diff $file /some/other/path/$file 
 el shell intenta expandir $file (¡de nuevo!). 
 Podría contener espacios, pero como ya configuramos IFS arriba, eso no será un problema aquí.
 Pero también podría contener caracteres comodín como * o ?, lo que provocaría un comportamiento impredecible. (Gracias a Gilles por señalar esto.) 
 Para decirle al shell que no expanda los caracteres comodín, coloque la variable entre comillas dobles, por ejemplo 
diff "$file" "/some/other/path/$file" 
 El mismo problema también podría afectarnos 
for file in `find . -name "*.csv"` 
 Por ejemplo, si tuviera estos tres archivos 
file1.csv file2.csv *.csv 
 (muy poco probable, pero aún posible) 
 Sería como si hubiera ejecutado 
for file in file1.csv file2.csv *.csv 
 que se expandirá a 
for file in file1.csv file2.csv *.csv file1.csv file2.csv 
 causando file1.csv y file2.csv para ser procesado dos veces. 
 En su lugar, tenemos que hacer 
find . -name "*.csv" -print | while IFS= read -r file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty done 
 read lee líneas de la entrada estándar, divide la línea en palabras de acuerdo con IFS y las almacena en los nombres de variable que usted especifique. 
 Aquí, «lo estamos diciendo no dividir la línea en palabras y almacenar la línea en $file. 
 También tenga en cuenta que  ha cambiado a read line </dev/tty. 
 Esto se debe a que dentro del ciclo, la entrada estándar proviene de find a través de la canalización. 
 Si hiciéramos read, consumiría parte o todo el nombre de un archivo, y algunos archivos se omitirían . 
 /dev/tty es el terminal desde donde el usuario está ejecutando el script. Tenga en cuenta que esto provocará un error si el script se ejecuta a través de cron, pero supongo que esto no es importante en este caso. 
 Entonces, ¿qué pasa si un nombre de archivo contiene nuevas líneas? 
 Podemos manejar eso cambiando -print a -print0 y usando read -d "" al final de un pipeline: 
find . -name "*.csv" -print0 | while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read char </dev/tty done 
 Esto hace que find ponga un byte nulo al final de cada nombre de archivo. Los bytes nulos son los únicos caracteres que no se permiten en los nombres de archivo, por lo que esto debería manejar todos los nombres de archivo posibles, sin importar cuán extraños sean. 
 Para obtener el nombre del archivo en el otro lado, usamos IFS= read -r -d "". 
 Donde usamos read arriba, usamos el delimitador de línea predeterminado de nueva línea, pero ahora, find utiliza nulo como delimitador de línea. En bash, no puede «pasar un carácter NUL en un argumento a un comando (incluso los incorporados), pero bash entiende -d "" en el sentido de  delimitado por NUL . Por lo tanto, usamos -d "" para hacer read use el mismo delimitador de línea que find. Tenga en cuenta que -d $"\0", por cierto, también funciona, porque bash que no admite bytes NUL lo trata como una cadena vacía. 
 Para ser correctos, también agregamos -r, que dice que no maneje barras invertidas en nombres de archivo especialmente. Por ejemplo, sin -r, \<newline> se eliminan y \n se convierte en n. 
 Una forma más portátil de escribir esto que no «requiere bash o zsh o recordando todas las reglas anteriores sobre bytes nulos (nuevamente, gracias a Gilles): 
find . -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read char </dev/tty " exec-sh {} ";" 
 *  3. Omitir directorios cuyo los nombres terminan en .csv 
find . -name "*.csv" 
 también coincidirán con directorios que se llaman something.csv. 
 Para evitar esto, agregue -type f al comando find. 
find . -type f -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty " exec-sh {} ";" 
 Como  glenn jackman  señala, en ambos ejemplos, los comandos a ejecutar para cada archivo son se ejecuta en una subcapa, por lo que si cambia alguna variable dentro del bucle, se olvidará. 
 Si necesita establecer variables y tenerlas aún configuradas al final del ciclo, puede reescribirlo para usar la sustitución de procesos como esta: 
i=0 while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty i=$((i+1)) done < <(find . -type f -name "*.csv" -print0) echo "$i files processed" 
 Tenga en cuenta que si intenta copiar y pegar esto en la línea de comando , read line consumirá echo "$i files processed", por lo que ese comando no se ejecutará. 
 Para evitar esto, podría eliminar read line </dev/tty y enviar el resultado a un localizador como less. 
  NOTAS  
 Eliminé el punto y coma (;) dentro del lazo. Puede devolverlos si lo desea, pero no son necesarios. 
 En estos días, $(command) es más común que `command`. Esto se debe principalmente a que es más fácil escribir $(command1 $(command2)) que `command1 \`command2\``. 
 read char realmente no lee un carácter.Lee una línea completa, así que la cambié a read line. 
 Comentarios 
 
 Este script falla si algún nombre de archivo contiene espacios o caracteres globbing de shell \[?*. El comando find genera un nombre de archivo por línea. Luego, el shell evalúa la sustitución del comando `find …` de la siguiente manera: 
-  Ejecute el comando 
find, tome su salida.  
-  Divida la salida 
find en palabras separadas. Cualquier carácter de espacio en blanco es un separador de palabras.  
-  Para cada palabra, si es un patrón globular, amplíelo a la lista de archivos con los que coincide. 
 
 Por ejemplo, supongamos que hay tres archivos en el directorio actual, llamados `foo* bar.csv, foo 1.txt y foo 2.txt. 
-  El comando 
find devuelve ./foo* bar.csv.  
-  El shell divide esta cadena en el espacio, produciendo dos palabras: 
./foo* y bar.csv.  
-  Desde 
./foo* contiene un metacarácter globbing, se expande a la lista de archivos coincidentes: ./foo 1.txt y ./foo 2.txt.  
-  Por tanto, el ciclo 
for se ejecuta sucesivamente con ./foo 1.txt, ./foo 2.txt y bar.csv.  
 Puede evitar la mayoría de los problemas en esta etapa si atenúa la división de palabras y ing off globbing. Para atenuar la división de palabras, establece la variable IFS en un solo carácter de nueva línea; de esta manera la salida de find sólo se dividirá en líneas nuevas y quedarán espacios. Para desactivar el globbing, ejecute set -f. Entonces, esta parte del código funcionará siempre que ningún nombre de archivo contenga un carácter de nueva línea. 
IFS=" " set -f for file in $(find . -name "*.csv"); do … 
 (Esto no es parte de su problema, pero recomiendo usar $(…) sobre `…`. Tienen el mismo significado, pero la versión de comillas inversas tiene reglas de comillas extrañas.) 
 Hay otro problema a continuación: diff $file /some/other/path/$file debería ser 
diff "$file" "/some/other/path/$file" 
 De lo contrario, el valor de $file se divide en palabras y las palabras se tratan como patrones globales, como con el comando substitutio anterior. Si debe recordar algo acerca de la programación de shell, recuerde esto:  use siempre comillas dobles alrededor de las expansiones de variables ($foo) y sustituciones de comandos ( $(bar)) , a menos que sepa que desea dividir. (Arriba, sabíamos que queríamos dividir la salida find en líneas). 
 Una forma confiable de llamar a find le está diciendo que ejecute un comando para cada archivo que encuentre: 
find . -name "*.csv" -exec sh -c " echo "$0" diff "$0" "/some/other/path/$0" " {} ";" 
 En este caso, otro enfoque es comparar los dos directorios, aunque debe excluya explícitamente todos los archivos «aburridos». 
diff -r -x "*.txt" -x "*.ods" -x "*.pdf" … . /some/other/path 
 Comentarios