Tengo el siguiente problema:
El directorio Example1
tiene tres archivos Example1
: Things
y Pictures
.
El directorio Example2
tiene tres archivos Example2
: Example3
y Pictures
.
Necesito una lista que muestre solo los archivos que coinciden con el nombre del directorio, esto es: Example1
y 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/something
en que las dos something
partes 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 \1
coincide con el mismo texto que coincide con el primer grupo, por lo tanto \(/[^/]*\)\1
coincide 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 find
que 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 -c
que 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 -f
prueba por una -e
prueba.
Respuesta3
Usar find -exec
:
find . -type f \
-exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
-print
Solo se -print
ejecutará cuando el resultado del [ ... ]
interior -exec sh -c '...'
sea verdadero.
Producción:
./Example1/Example1
./Example2/Example2