usando find, sed e xargs para corrigir nomes de arquivos da recuperação de dados em um mac

1

Ok, eu estou indo em círculos. Estou usando este comando

find . -print0 -name '*.1.*' | sed -e 'p;s/\.1//' | xargs -0 -n2 mv

Para tentar renomear centenas de arquivos com ".1". adicionado imediatamente antes da extensão do arquivo quando eles foram arquivados depois que alguém acidentalmente excluiu 200 GB de dados.

Fico preso entre os mac xargs interpretando espaços em nomes de arquivos como argumentos separados e não sendo possível definir o delimitador para apenas novas linhas, não espaços. Eu não consigo descobrir como ter impressão do caractere '\ 0', bem como novas linhas entre. Alguma idéia de como fazer isso funcionar? Eu tenho procurado em círculos e parece simplesmente estar em um ambiente de mac está fazendo isso mais complicado do que o necessário.

Como alternativa, tentar renomear o comando, mas ainda com problemas

 find . -name '*.1.*' -type f -exec rename -n 's/\.1//' '{}' \;

RESPOSTA como por @Wildcard abaixo

find . -name '*.1.*' -type f -exec sh -c '
  for f do
    suf="${f##*.1}"
    new="${f%.1.*}$suf"
    if [ -e "$new" ]; then
      printf "Cannot move file <%s>\n" "$new"
    else
      mv -n "$f" "$new"
    fi
  done
  ' find-sh {} +
    
por FaultyJuggler 05.12.2017 / 01:29

1 resposta

3

O seguinte deve ser seguro sempre e deve funcionar em um Mac:

find . -name '*.1.*' -type f -exec sh -c '
  for f do
    suf="${f##*.1.}"
    new="${f%.1.*}.$suf"
    if [ -e "$new" ]; then
      printf "Cannot move file <%s>\n" "$new"
    else
      mv -n "$f" "$new"
    fi
  done
  ' find-sh {} +

Observe que mv -n sai com êxito sem renomear o arquivo, se ele substituir um arquivo existente. Você provavelmente gostaria que fosse relatado. Então isso acontece.

Além disso, no caso da borda ímpar, onde há um diretório com o novo nome de destino, mv moveria o arquivo para ele sem a verificação de segurança que adicionei (mesmo com -n ) . Isso não seria desejável também.

Se um arquivo tiver mais de uma .1. string em seu nome, esse comando removerá apenas o último. (O que provavelmente está mais próximo do que foi planejado do que remover o primeiro ).

Teoricamente, você não precisa da opção -n com o bloco if da verificação de segurança, mas eu a deixei protegendo os dados em caso de condições de corrida (se algum outro processo criar um arquivo de destino antes de você mova um arquivo sobre esse nome).

Mais importante ainda, isso não vai explodir, não importa quão bizarros sejam seus nomes de arquivo. Mesmo se eles tiverem novas linhas incorporadas, caracteres de aspas simples, asteriscos e todo tipo de coisa.

Pense nisso, porém, não tenho certeza de quão bem a expansão do parâmetro bash funciona no Unicode.

    
por 05.12.2017 / 02:14