Encontre arquivos que tenham o mesmo nome do diretório

Encontre arquivos que tenham o mesmo nome do diretório

Eu tenho o próximo problema:

O diretório Example1possui três arquivos Example1: Thingse Pictures.

O diretório Example2possui três arquivos Example2: Example3e Pictures.

Preciso de uma lista mostrando apenas os arquivos que correspondem ao nome do diretório, isto é: Example1e Example2. Eu tentei com diff, find, localizar e ls... mas não consegui nada.

Responder1

Você pode combinar facilmente nomes de arquivos que tenham o mesmo nome do diretório que os contém com uma regex usando uma referência anterior. Esses são nomes de arquivos no formato what/ever/something/somethingem que as duas somethingpartes são idênticas e não contêm barras. Na sintaxe BRE regex, [^/]*corresponde a qualquer string que não contenha uma barra, \(/[^/]*\)corresponde a uma barra seguida por qualquer número de caracteres não-barra e torna tudo um grupo, e \1corresponde ao mesmo texto que corresponde ao primeiro grupo, portanto \(/[^/]*\)\1corresponde a dois segmentos de caminho com o mesmo nome. Adicione .*no início para corresponder aos componentes do diretório anterior.

Com GNU find, FreeBSD find, macOS find ou qualquer outro findque suporte -regex:

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

Responder2

Como geralmente há menos diretórios do que arquivos, vamos procurar todos os diretórios e testar se eles contêm o nome de arquivo necessário.

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

Isso imprimiria os nomes de caminho de todos os arquivos regulares (e links simbólicos para arquivos regulares) localizados em um diretório com o mesmo nome do arquivo.

O teste é feito em um script curto em linha sh -cque obterá vários nomes de caminhos de diretório como argumentos. Ele itera sobre cada nome de caminho de diretório e constrói um nome de caminho de arquivo com o nome que estamos procurando. O ${dirpath##*/}no código pode ser substituído por $(basename "$dirpath").

Para o exemplo de estrutura de diretório fornecido, isso resultaria

./Example1/Example1
./Example2/Example2

Para apenas testarqualquer nome, não apenas arquivos normais, altere o -fteste para um -eteste.

Responder3

Usar find -exec:

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

O -printsó será executado quando o resultado do [ ... ]interior do -exec sh -c '...'for verdadeiro.

Saída:

./Example1/Example1
./Example2/Example2

informação relacionada