Usando mv para ir para outro diretório e renomear de uma só vez

1

Eu gostaria de saber cada arquivo que tem + 100Mb e não foi acessado no último mês, e escrevi com sucesso:

find / -size +100M -atime +30

E agora eu quero mover esses arquivos para uma pasta chamada / big-not-used mudando seu nome como: file_nameYYYYMMDD onde file_name é o nome do arquivo original e YYYYMMDD é a data de hoje, em ano mês dia. Por exemplo, film.mkv vai para /big-not-used/film.mkv20161031

Minha sentença seria:

find / -size +100M -atime +30 -exec mv {} /big-not-used/... \;

Mas não sei como acrescentar a data de hoje no nome do arquivo. Descobri que date +%Y-%m-%d outputs: 2016-10-31 , que é útil. Agora a dúvida é como obter o nome desse arquivo? Segue: link

... -exec basename {} \;

Talvez?:

find / -size +100M -atime +30 -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

Mas dá um erro porque o basename está respondendo com o caminho completo do arquivo em vez do nome que eu usaria:

${var##/*/}

para obter o nome do arquivo, mas a questão é como eu insiro o que basename {} responde no var na expressão anterior!?.

Talvez?

$(${$(basename {})##/*/})

Mas é dito erro sintáctico perto do inesperado '}' ...

    
por enoy 30.10.2016 / 11:32

2 respostas

0

Você estava chegando perto:

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

Mas sem citar, a expansão do shell das construções $(...) acontece antes que o comando find seja executado . Em outras palavras, dada a linha de comando acima, que realmente é executada é:

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/{}2016-10-30 \;

Porque o resultado de $(basename {}) é apenas {} e é por isso que você acaba com o nome completo do caminho. Tente isso:

find / -size +100M -atime +30 \
  -exec sh -c 'mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

Para testar as coisas, você pode substituir mv por echo mv , assim:

find / -size +100M -atime +30 \
  -exec sh -c 'echo mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

... e veja como são os comandos gerados.

    
por 30.10.2016 / 14:00
0

Eu melhorei um pouco a solução da lark para fazer apenas uma única chamada sh :

find / -size +100M -atime +30 -exec sh -c \
  'for f do mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"; done' sh {} +

Como alternativa, sem nenhuma chamada sh :

while IFS= read -r f; do
  mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"
done < <(find / -size +100M -atime +30)

(Sob o pressuposto de que os nomes dos arquivos não contêm novas linhas.)

Para depuração, talvez você queira adicionar -v a mv (se for compatível).

    
por 30.10.2016 / 20:07

Tags