Gostaria de saber todos os arquivos que têm +100Mb e não foram acessados no último mês, e escrevi com sucesso:
find / -size +100M -atime +30
E agora quero mover esses arquivos para uma pasta chamada /big-not-used alterando seu nome como: file_nameYYYYMMDD
onde file_name é o nome do arquivo original e YYYYMMDD é a data de hoje, no ano mês dia. Por exemplo film.mkv
vai para/big-not-used/film.mkv20161031
Minha frase seria:
find / -size +100M -atime +30 -exec mv {} /big-not-used/... \;
Mas não sei como acrescentar a data de hoje ao nome do arquivo. Eu descobri que date +%Y-%m-%d
resulta: 2016-10-31
o que é útil. Agora a dúvida é como conseguir o nome desse arquivo? Seguindo:
https://stackoverflow.com/questions/5456120/how-to-only-get-file-name-with-linux-find
... -exec basename {} \;
Talvez?:
find / -size +100M -atime +30 -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;
Mas dá um erro porque 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 inserir quais basename {}
respostas no var na expressão anterior!?.
Talvez?
$(${$(basename {})##/*/})
Mas diz erro sintático próximo ao inesperado '}'...
Responder1
Você estava chegando perto de:
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 aconteceantes do find
comando ser executado. Em outras palavras, dada a linha de comando acima, o que realmente é executado é:
find / -size +100M -atime +30 \
-exec mv {} /big-not-used/{}2016-10-30 \;
Porque o resultado de $(basename {})
é justo {}
e é por isso que você obtém o nome do caminho completo. Em vez disso, tente isto:
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.
Responder2
Melhorei um pouco a solução do Lark para fazer apenas uma sh
chamada:
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 {} +
Alternativamente, sem nenhuma sh
chamada:
while IFS= read -r f; do
mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"
done < <(find / -size +100M -atime +30)
(Último, sob a suposição de que os nomes dos arquivos não contêm novas linhas.)
Para depuração, você pode querer adicionar -v
( mv
se for compatível).