Para ver uma listagem, aqui estão duas variantes, uma que recorre a subdiretórios e outra que não. Todos usam sintaxe específica para bash, ksh e 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)
Mais curto, em 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))
O comando comm
lista as linhas comuns a dois arquivos ( comm -12
), que estão apenas no primeiro arquivo ( comm -23
) ou que estão apenas no segundo arquivo ( comm -13
). Os números indicam o que é subtraído da saída¹. Os dois arquivos de entrada devem ser classificados.
Aqui, os arquivos são, na verdade, a saída de um comando. O shell avalia a construção <(…)
fornecendo um arquivo “falso” (um FIFO ou um descritor de arquivo /dev/fd/
) como argumento para o comando.
Então aqui os menos sayers são totalmente justificados.
Se você deseja executar ações nos arquivos, provavelmente desejará iterar os arquivos de origem.
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