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