Meu conhecimento de Unix não é muito bom. Estou tentando escrever um script de shell para renomear um conjunto de arquivos em um diretório, como 1709532255.mp4
, 20240304_070415.mp4
onde 1709532255
é sempre uma época.
eu achei aquilo
date -d @1708532255 +'%Y%m%d_%H%M%S'
... me dá o formato desejado, mas não consigo fazê-lo funcionar no script.
Aqui meu roteiro:
#!/bin/bash
for file in /media/HAVideo/Eingang/Test/2/*.mp4
do
filename=`echo "${file}" | cut -d'.' -f1`
readable=`date -d @$filename +"%Y%m%d%H%M%S"`
mv "${file}" "${readable}"
done
A saída é:
...
date: invalid date '@/media/HAVideo/Eingang/Test/2/1709532255'
mv: can't rename '/media/HAVideo/Eingang/Test/2/1709532255.mp4': No such file or directory
...
Você acabou de perder um
cd
:Mas há alguns problemas.
Use
$( )
em vez de crases. E recue corretamente.Consulte http://mywiki.wooledge.org/BashFAQ/082
Uma versão melhor:
${file%.*}
é uma expansão de parâmetro integradaVeja: http://mywiki.wooledge.org/BashFAQ/073 e
LESS='+/Parameter Expansion' man bash
veja também wiki.bash-hackers.org/syntax/pe
Como esse é um
sh
operador padrão (do ksh) e não há bashismo nesse código, você pode alterar o shebang para#! /bin/sh -
e remover a dependência do bash. Porém , essedate -d
é um GNUismo não padrão, que você pode evitar usando asprintf '%(format)T'
versões recentes do bash (copiado do ksh93).Com
zsh
:(remova o
-n
(ensaio) se estiver satisfeito).Tenha em atenção que, embora 1709532255 seja independente do fuso horário,
20240304_060415
não o é e é ambíguo. Você pode remover a ambigüidade e ainda usar a hora local usando o formato de data no estilo ISO8601, onde o deslocamento para UTC é incluído, substituindo por,%Y%m%d_%H%M%S
por%FT%T%z
exemplo, onde eu obteria2024-03-04T06:04:15+0000
e você provavelmente obteria2024-03-04T07:04:15+0100
o mesmo carimbo de data e hora, mas em dois fusos horários diferentes .O motivo pelo qual você está vendo o erro:
é porque você está passando o caminho completo do arquivo, menos a extensão, devido ao seu
cut
comando.está avaliando para:
Portanto,
filename
é/media/HAVideo/Eingang/Test/2/1709532255
.Seu script funciona principalmente. Modifiquei a
filename=...
linha para recuperar apenas o nome base do arquivo, em vez do caminho completo:claro, você poderia ir além e remover o desnecessário ,
cut
poisbasename
pode remover a extensão do arquivo e renomear as variáveis para que o código fique um pouco mais claro:NÃO TESTADO
Usando perl (utilizável em qualquer sistema operacional).
Time::Piece
O módulo do vem com Perl, não há necessidade de instalá-lo.Alguns caras ofereceram suas soluções, então me concentrei em duas coisas.
Para fazer o mínimo de modificações possível
Para se livrar da sintaxe à prova de falhas desnecessária
Na produção do mundo real, há muitas ocasiões em que você não consegue obter espaços nos nomes dos arquivos sob nenhuma condição. Então, eu pessoalmente aconselho você a se livrar de citações desnecessárias nas últimas 2 linhas do ciclo.
Você pode fazer isso se souber exatamente o que está fazendo. Então você terá uma sintaxe melhor e mais limpa em seus scripts.
Também uma palavra sobre backticks. Gosto do conselho da resposta com melhor classificação acima. Geralmente é melhor usar o formulário $(). Ainda assim, não há grande problema com crases, a menos que você esteja começando a fazer inclusões como
\
` `.