Eu tenho arquivos e diretórios começando com"ícone de categoria-"em muitos subdiretórios. Estou tentando renomeá-los recursivamente para"ícones de categoria-". Observe que adicionei faltando"g"para ocategoriae"é"no fim deícones.
Eu li muitas outras questões relacionadas à renomeação de vários arquivos e diretórios, mas não consegui fazer nenhuma delas funcionar para mim!
Uma pequena explicação sobre a resposta seria muito apreciada.
EDITADO: Aqui está um exemplo da minha estrutura de diretórios:
test/cateory-icon-archery/cateory-icon-archery.png
[email protected]
test/cateory-icon-automotive/cateory-icon-automotive.png
[email protected]
Responder1
Como você precisa fazer isso recursivamente, find
é a melhor ferramenta a ser usada. Para alterar o nome, você pode usar sh
na -exec
chamada. Aqui está um exemplo:
find /some/path -name 'cateory-icon' -exec sh -c 'mv "$1" "${1%/*}/category-icon-${1#cateory-icon-*}"' -- {} \;
A ${1#cateory-icon-*}
expansão recebe o nome do arquivo depois de cateory-icon
.
Responder2
No zsh, coloque o seguinte em seu .zshrc
(ou execute-o na linha de comando para uma única vez):
autoload zmv
alias zcp='zmv -C'
alias zln='zmv -L'
Ozmv
funçãocombinado com zshcuringas e recursos globbingpermite fácil renomeação e cópia de arquivos. Aqui estão várias maneiras de fazer o que você deseja:
zmv '(**/)cateory-icon-(*)' '${1}category-icons-$2'
zmv -w '**/cateory-icon-*' '${1}category-icons-$2'
zmv '**/cateory-icon-(*)' '$f:h/category-icons-$1'
Explicação para alguns recursos do zsh:
**/
corresponde a arquivos em subdiretórios recursivamente.- Os parênteses na expressão de origem designam grupos.
$NUM
ou${NUM}
na expressão de substituição é substituída pela parte do nome original contida no NUMésimo grupo. - Os parênteses
**
são um pouco peculiares: você só pode colocá-los**/
, nem mais, nem menos. - A
-w
opção dezmv
coloca automaticamente cada curinga em um grupo (pois**
, é a**/
parte que está em um grupo, com o final/
). $f
na substituição significa todo o nome do arquivo de origem.$VAR:h
significa a parte do diretório de$VAR
. Isso geralmente ocorre$VAR
até o último/
, mas todos os casos extremos (foo
,foo/
,/
,…) são tratados corretamente. O nome base está disponível como$VAR:t
.
Responder3
Usando Perl para máxima portabilidade:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
use File::Copy qw(move);
my $new_name;
finddepth( sub {
if(/cateory-icon/){
($new_name = $File::Find::name) =~ s{.*/\Kcateory-icon}{category-icons};
move $File::Find::name => $new_name;
}
},
'.')
Explicação
- Isso faz uso de 2 módulos principais Perl:
File::Find
para travessia recursiva de árvores de diretórios eFile::Copy
para cópia/movimentação recursiva de diretórios. - A
finddepth
função (fromFile::Find
) percorre a lista de diretórios fornecidos como seu segundo argumento (.
neste caso é o diretório atual; modifique conforme necessário). - O primeiro argumento
finddepth
é uma referência de sub-rotina que é executada para cada arquivofinddepth
encontrado à medida que ele percorre a árvore. - Iniciamos esta sub-rotina por uma
if
condição: se o nome do arquivo correspondente contém o padrãocateory-icon
, então formamos o novo nome fazendo as correções necessárias e usamos amove
função (deFile::Copy
) para modificar o nome atual para o novo nome.
Isenção de responsabilidade
Este código não foi testado. Experimente primeiro em uma árvore de diretórios fictícia!