Se eu acertei, você tem arquivos e diretórios como este:
$ mkdir dir{1,2,3} ; touch file{1,2,3} .file{1,2,3}
$ ls -A
.file1 .file2 .file3 dir1 dir2 dir3 file1 file2 file3
e deseja renomear os dirs para _dir1 , _dir2 , _dir3 ?
Esse find / printf mv parece factível. Vamos ver o que é impresso:
$ find . -type d -name '*' -printf "mv \"%h/%f\" \"%h/_%f\"\n"
mv "./." "./_."
mv "./dir2" "./_dir2"
mv "./dir3" "./_dir3"
mv "./dir1" "./_dir1"
Esse primeiro comando soltará um erro, já que o "ponto" é especial e você não pode renomeá-lo. Mas os outros devem estar ok, e deve renomear os diretórios como você queria:
$ find . -type d -name '*' -printf "mv \"%h/%f\" \"%h/_%f\"\n" | sh
mv: cannot move ‘./.’ to ‘./_.’: Device or resource busy
$ ls -d _dir*
_dir1 _dir2 _dir3
Mas os comandos de tubulação para um shell são um pouco feios e, se os nomes dos arquivos forem estranhos, os resultados serão surpreendentes (por exemplo, se eles contiverem $ sinais que dispararão variáveis ou substituição de comandos no shell). / p>
Se os arquivos estiverem todos em um nível, isso deve ser feito:
for x in * ; do [ -d "$x" ] && mv "$x" "_$x" ; done
(Embora se _$x já exista, $x será movido para ele.)
Se você deseja incluir diretórios cujos nomes começam com um ponto, use shopt -s dotglob antes.
Isso também está próximo:
find . -type d -exec rename 's/^/_/' {} \;
Mas, como find fornece rename aos caminhos que começam com ./ , precisamos levar isso em consideração. Em apenas um nível, isso deve ser feito (altera o primeiro ./ para ./_ ):
find . -type d -exec rename 's,^./,./_,' {} \;
Para obter os diretórios em todos os níveis, find -execdir pode ser mais fácil de usar. Ele executa o comando no diretório do arquivo. Precisamos de -depth para manipular as renomeações na ordem correta.
find . -depth -type d -execdir rename 's,^./,./_,' {} \;
Talvez adicione ! -name . também. por exemplo.
$ mkdir foo foo/dir1 foo/dir2
$ find . -depth \! -name . -type d -execdir rename 's,^./,./_,' {} \;
$ ls _foo
_dir1 _dir2