Busque archivos que tengan el mismo nombre que el directorio

Busque archivos que tengan el mismo nombre que el directorio

Tengo el siguiente problema:

El directorio Example1tiene tres archivos Example1: Thingsy Pictures.

El directorio Example2tiene tres archivos Example2: Example3y Pictures.

Necesito una lista que muestre solo los archivos que coinciden con el nombre del directorio, esto es: Example1y Example2. He probado con diff, find, localizar y ls... pero no he conseguido nada.

Respuesta1

Puede hacer coincidir fácilmente los nombres de archivos que tienen el mismo nombre que el directorio que los contiene con una expresión regular utilizando una referencia inversa. Estos son nombres de archivos en la forma what/ever/something/somethingen que las dos somethingpartes son idénticas y no contienen una barra. En la sintaxis de expresiones regulares BRE, [^/]*coincide con cualquier cadena que no contenga una barra, \(/[^/]*\)coincide con una barra seguida de cualquier número de caracteres que no sean una barra y convierte todo en un grupo, y \1coincide con el mismo texto que coincide con el primer grupo, por lo tanto \(/[^/]*\)\1coincide con dos segmentos de ruta con el mismo nombre. Agregue .*al principio para que coincida con los componentes del directorio anterior.

Con GNU find, FreeBSD find, macOS find o cualquier otro findque admita -regex:

find . -regex '.*\(/[^/]*\)\1'

Respuesta2

Dado que generalmente hay menos directorios que archivos, busquemos todos los directorios y luego probemos si contienen el nombre de archivo requerido.

find . -type d -exec sh -c '
    for dirpath do
        filepath="$dirpath/${dirpath##*/}"
        [ -f "$filepath" ] && printf "%s\n" "$filepath"
    done' sh {} +

Esto imprimiría los nombres de ruta de todos los archivos normales (y enlaces simbólicos a archivos normales) que se encuentran en un directorio que tiene el mismo nombre que el archivo.

La prueba se realiza en un breve script en línea sh -cque obtendrá una serie de nombres de rutas de directorio como argumentos. Itera sobre cada nombre de ruta de directorio y construye un nombre de ruta de archivo con el nombre que estamos buscando. El ${dirpath##*/}en el código podría reemplazarse por $(basename "$dirpath").

Para la estructura de directorios de ejemplo dada, esto generaría

./Example1/Example1
./Example2/Example2

Para simplemente probarcualquier nombre, no solo archivos normales, cambie la -fprueba por una -eprueba.

Respuesta3

Usar find -exec:

find . -type f \
  -exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
  -print

Solo se -printejecutará cuando el resultado del [ ... ]interior -exec sh -c '...'sea verdadero.

Producción:

./Example1/Example1
./Example2/Example2

información relacionada