Necessidade de remover apóstrofos de arquivos. Eu tentei várias abordagens, também do Stackexchange .
Estou em um Synology NAS, então não tenho Python ou Perl e, além disso, tenho que excluir certos diretórios (find -prune).
O seguinte comando find parece funcionar geralmente durante o teste (usando echo):
find . -depth \( -type d -name "@*" -o -name "*#recycle*" -o -name "*SynoResource*" -prune \) -o \( -name "*\'*" -execdir bash -c 'for f; do echo mv ${f/\\\'/\\\\'} `echo $f | sed 's/\\\'/X/g'`; done' _ {} + \)
Para um arquivo como "911's.zip", substituir o apóstrofo ' por um X gera o seguinte resultado (usando o comando acima):
mv ./911's.zip ./911Xs.zip
Quando removo o "echo" para executar o comando, recebo o seguinte erro:
mv: target '911Xs.zip' is not a directory
Em um shell interativo, posso renomear o arquivo com este comando:
mv 911\'s.zip 911Xs.zip
Claro, já tentei escapar do ' (mesmo com vários \, como em ${f/\'/X}
), mas não funciona.
Qualquer ideia?
Muito obrigado,
Gary
Vários problemas:
-prune
com-depth
os-depth
processos que saem primeiro, portanto-prune
, não tem efeito, pois chega tarde demais, depois que todo o conteúdo do diretório já foi processado.-prune
está fora do lugar. Onde você colocá-lo, ele se aplicaria apenas aos arquivos que correspondem a-name "*SynoResource*"
. O mesmo para o-type d
qual se aplica apenas a-name "@*"
.echo
geralmente não pode ser usado para produzir dados arbitrários.'
string entre aspas simples. Se você precisar passar um'
literalmente para algum comando, precisará citá-lo usando outro operador de citação do shell ("..."
ou barra invertida) e fora das aspas simples.'
não é especial paramv
,sed
nemfind
, não há necessidade de escapar disso para eles. É especial apenas para o shell, onde é um operador de citação forte.$(...)
em vez disso obsoleto`...`
(o que também adiciona ainda mais complicações quando a barra invertida está envolvida).Então aqui:
Aqui, como
-prune
não pode ser usado com-depth
, estamos usando-path
(também conhecido como-wholename
GNUfind
) para filtrar os arquivos nesses diretórios excluídos com base em seu caminho completo. Isso significa, no entanto, quefind
descerá para os diretórios que não são ideais do ponto de vista do desempenho.Usar
-execdir
significa que você está renomeando apenas o nome base, o que é bom, mas isso também significa que você acaba executando pelo menos umbash
por diretório que contém arquivos com'
s. Alternativamente, você poderia fazer:Isso o torna mais eficiente, embora menos seguro, caso alguém renomeie arquivos e diretórios enquanto o script está em execução.
Para uma simulação, você pode substituir o
mv
comando por:Isso é melhor do que usar
echo
asbash
aspas quando necessário em sua saída de rastreamento para torná-la inequívoca. A saída de rastreamento parecerá um código de shell válido que pode ser usado para executar o mesmo comando.Lá, usar
-exec
em vez de-execdir
também deixa o rastreamento claro sobre quais arquivos seriam renomeados.Para usar
-prune
, mas ainda processar a profundidade do diretório primeiro, uma alternativa seria usar GNUtac -s ''
se disponível (junto com GNUxargs
) na saída defind -print0
para revertê-lo:Sem GNU
tac
,xargs
mas se o seu bash for da versão 4.4 ou superior, você também pode fazer:(cuidado eu não testei nada disso).