No se especificó, pero aquí hay una solución sin expresiones regulares si alguien está interesado.
Podemos usar find . -type fpara obtener archivos, luego utilizar dirnamey basenameescribir el condicional. Las utilidades tienen el siguiente comportamiento:
$ find . -type f
./dir2/spam/spam.pdf
./dir2/dir2.tex
./dir3/dir3.pdf
./dir3/eggs/eggs.pdf
./dir1/dir1.pdf
./dir1/dir1.txt
basenamedevuelve solo el nombre del archivo después del último /:
$ for file in $(find . -type f); do basename $file; done
spam.pdf
dir2.tex
dir3.pdf
eggs.pdf
dir1.pdf
dir1.txt
dirnameda todo el camino hasta la final /:
$ for file in $(find . -type f); do dirname $file; done
./dir2/spam
./dir2
./dir3
./dir3/eggs
./dir1
./dir1
Por lo tanto, basename $(dirname $file)proporciona el directorio principal del archivo.
$ for file in $(find . -type f); do basename $(dirname $file) ; done
spam
dir2
dir3
eggs
dir1
dir1
Solución
Combine lo anterior para formar el condicional "$(basename $file)" = "$(basename $(dirname $file))".pdf, luego solo imprima cada resultado findsi ese condicional devuelve verdadero.
$ while read file; do if [ "$(basename "$file")" = "$(basename "$(dirname "$file")")".pdf ]; then echo $file; fi done < <(find . -type f)
./dir2/spam/spam.pdf
./dir3/dir3.pdf
./dir3/eggs/eggs.pdf
./dir1/dir1.pdf
./Final Thesis/grits/grits.pdf
./Final Thesis/Final Thesis.pdf
En el ejemplo anterior, hemos agregado un directorio / archivo con espacios en el nombre para tratar ese caso (gracias a @Kusalananda en los comentarios)