Você poderia fazer algo assim:
for dir in ccc ddd lll; do
find "main/$dir" -type f -print0 |
while IFS= read -r -d '' f; do
dd=$(dirname "$f")
new="${f/main\/}"
new="${new//\//_}"
mv "$f" "$dd"/"$new"
done
done
Após o script acima, seus arquivos ficarão assim:
.
'-- main
|-- ccc
| |-- fo01
| | |-- ccc_fo01_c_000
| | '-- ccc_fo01_c_001
| '-- fo02
| |-- ccc_fo02_c_000
| '-- ccc_fo02_c_001
|-- ddd
| |-- fo01
| | |-- ddd_fo01_d_000
| | '-- ddd_fo01_d_001
| '-- fo02
| |-- ddd_fo02_d_000
| '-- ddd_fo02_d_001
'-- lll
|-- fo01
| |-- lll_fo01_l_000
| '-- lll_fo01_l_001
'-- fo02
|-- lll_fo02_l_000
'-- lll_fo02_l_001
Explicação
-
for dir in ccc ddd lll; do ...; done
: faça isso apenas para esses três nomes de diretório, salvando cada um deles como$dir
. -
find "main/$dir" -type f -print0 |
: localize todos os arquivos (type f
) emmain/$dir
e imprima-os separados pela cadeia nula (-print0
) para garantir que funcione mesmo se os nomes de arquivos / diretórios contiverem novas linhas. -
while IFS= read -r -d '' f; do
: iterará os resultados defind
, salvando cada um como$f
. OIFS=
é necessário para evitar a quebra no espaço em branco, o-r
é para que as barras invertidas não sejam tratadas especialmente e o-d ''
permite a leitura da entrada delimitada por nulo. -
dd=$(dirname "$f")
:$dd
agora é o diretório onde o arquivo atual reside. Por exemplo,main/ccc/fo01
. -
new="${f/main\/}"
: está usando as habilidades de do shell para remover a stringmain/
de o caminho do arquivo. -
new="${new//\//_}"
: como acima apenas agora estamos substituindo todos os/
por sublinhados. Isso resulta em uma string comoccc_fo01_c000
. -
mv "$f" "$dd"/"$new"
: finalmente, renomeamos o arquivo original$f
para$dd/$new
. Lembre-se de que$dd
é o diretório em que esse arquivo foi encontrado e$new
agora é o nome para o qual você deseja renomeá-lo.
Sugiro que você adicione um echo
antes do mv
para testar antes de fazer isso.