Compara recursivamente los contenidos del directory por nombre, ignorando las extensiones de files

Tengo un directory que contiene aproximadamente 7,000 files de música. Utilicé lame para recodificar recursivamente todos los files en un directory separado, dando como resultado todos los files con la misma ruta relativa y el mismo nombre de file. Los files de salida tienen una extensión .mp3, pero algunos de los files de input tienen diferentes extensiones (.wma, .aac, etc.).

Veo que hay una diferencia en el conteo de files de ~ 100 files que faltan en el directory de salida. Lo que quiero hacer es ejecutar una comparación de los dos directorys y get una list de los files que existen en el origen, pero no en el destino. Esto sería lo suficientemente simple, excepto que necesito ignorar las diferencias en la extensión del file.

Intenté usar rsync con la ejecución en seco activada, pero no pude encontrar una manera de ignorar las extensiones de file. También probé con diff pero no pude encontrar una opción para verificar solo por nombre pero ignorar las extensiones de file. Empecé a pensar que podría hacer un l recursivo en ambos directorys, eliminar las extensiones de file y luego comparar los resultados, pero realmente no tengo idea de por dónde empezar modificando la salida de ls utilizando sed o awk ya que soy un competidor novato con esos.

Para ver una list, aquí hay dos variantes, una que recurre a subdirectorys y otra que no. Todos usan syntax específica para bash, ksh y zsh.

comm -3 <(cd source && find -type f | sed 's/\.[^.]*$//' | sort) \ <(cd dest && find -type f | sed 's/\.[^.]*$//' | sort) comm -3 <(cd source && for x in *; do printf '%s\n' "${x%.*}"; done | sort) \ <(cd dest && for x in *; do printf '%s\n' "${x%.*}"; done | sort) 

Más corto, en zsh:

 comm -3 <(cd source && print -lr **/*(:r)) <(cd dest && print -lr **/*(:r)) comm -3 <(print -lr source/*(:t:r)) <(print -lr dest/*(:t:r)) 

El command comm enumera las líneas que son comunes a dos files ( comm -12 ), que están solo en el primer file ( comm -23 ) o que están solo en el segundo file ( comm -13 ). Los numbers indican lo que se resta de la salida¹. Los dos files de input deben estar orderados.

Aquí, los files son, de hecho, el resultado de un command. El shell evalúa el constructo <(…) proporcionando un file "falso" (un FIFO o un descriptor de file /dev/fd/ named) como argumento para el command.

¹ Así que aquí los que dicen less están completamente justificados.


Si desea realizar acciones en los files, es probable que desee iterar sobre los files de origen.

 cd source for x in *; do set -- "…/dest/${x%.*}".* if [ $# -eq 1 ] && ! [ -e "$1" ]; then echo "$x has not been converted" elif [ $# -gt 1 ]; then echo "$x has been converted to more than one output file: " "$@" else echo "$x has been converted to $1" fi done