Copie todos os arquivos de subdiretórios e subsubdiretórios para o diretório principal modificando os nomes dos arquivos adicionando o prefixo de todos os diretórios pais

Copie todos os arquivos de subdiretórios e subsubdiretórios para o diretório principal modificando os nomes dos arquivos adicionando o prefixo de todos os diretórios pais

Seguindo estas duas postagens:

https://askubuntu.com/questions/871898/move-files-to-parent-directory-prefixing-file-name-with-former-subdirectory-nam

https://askubuntu.com/questions/870844/recursively-add-directory-name-to-file-name

Eu gostaria de fazer o mesmo, mas copiando em vez de mover. Simplesmente, eu tenho um diretório contendo subdiretórios e subsubdiretórios, onde existem alguns arquivos dentro. Quero copiar todos os arquivos para outra pasta de destino, mas como alguns arquivos têm nomes exatos, quero anexar o nome dos diretórios pais como um prefixo aos nomes dos arquivos.

Estou rodando no Ubuntu 16.04

Responder1

Tentar:

find  -name "*.dat" -exec bash -c 'echo cp "$1" "$(sed -e s:/:-:g -e s:^.-:./: <<<"$1")"' tinyscript {} \;

(remova o "eco" se os comandos parecerem bons)

.
└── 1
    └── 2
        ├── 3
        │   └── 4
        │       └── foo.dat
        └── foo.dat

Rendimentos:

cp ./1/2/3/4/foo.dat ./1-2-3-4-foo.dat
cp ./1/2/foo.dat ./1-2-foo.dat

Basicamente, você executa um pequeno script ad-hoc ( cp "$1" "$(sed -e s:/:-:g -e s:^.-:./: <<<"$1")"em cada arquivo correspondente e esse script gera o nome de destino substituindo tudo /no caminho de origem por um -. A tinyscriptstring pode ser qualquer coisa, é apenas um nome usado como nome do script em caso de erros.

Responder2

Favorecendo a simplicidade em detrimento do desempenho, isso não é particularmente eficiente (devido ao início de um processo bash para cada arquivo). Se você tiver muitos arquivos e/ou o tempo for um fator, uma solução mais envolvente pode ser necessária.

find yourdirectory/ -type f -print0 | xargs -0 -I% bash -c 'F="%" ; echo cp "${F}" "${F//\//-}"'

informação relacionada