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/$dire 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"):$ddagora é 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$fpara$dd/$new. Lembre-se de que$ddé o diretório em que esse arquivo foi encontrado e$newagora é o nome para o qual você deseja renomeá-lo.
Sugiro que você adicione um echo antes do mv para testar antes de fazer isso.