stat's
output é um timestamp do Unix, também chamado segundos desde a Epoch .
Todos os coreutils GNU que aceitam uma data permitem que você coloque um timestamp, prefixando o timestamp com um @
.
Então tente isso
touch -d @$ORIGTS $f
Estou tentando OCR alguns documentos insitu (a partir de uma linha de comando do Linux em um compartilhamento do Windows). O processo de OCR é encontrado e eu tenho confuso usando o comando find para canalizar os arquivos através do loop corretamente.
No entanto, preciso preservar o timestamp original para modificado. No momento, estou tentando usar stat e touch conforme abaixo:
#!/bin/bash
OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for f in 'find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"'
do
ORIGTS='stat -c "%Y" $f'
sudo /opt/ABBYYOCR9/abbyyocr9 -rl English -pi -if $f -f PDFA -paemImageOnText -pafpr original -of $f
touch -t $ORIGTS $f
done
IFS=$OLDIFS
É claro que o comando de toque falha. rodando os comandos separadamente percebo "stat -c" é algo ao longo das linhas deste:
1334758696
que é como nenhuma data que eu conheço. Sinto-me como se estivesse perto, mas não consigo descobrir como converter a data em que tenho uma versão amigável ao toque. É alguma forma de segundos de alguma coisa?
stat's
output é um timestamp do Unix, também chamado segundos desde a Epoch .
Todos os coreutils GNU que aceitam uma data permitem que você coloque um timestamp, prefixando o timestamp com um @
.
Então tente isso
touch -d @$ORIGTS $f
touch
pode usar o registro de data e hora de um arquivo usando a opção -r
. Você pode querer dar saída para um arquivo diferente (suponho que -if
seja o arquivo de entrada e -of
seja o arquivo de saída)
for f in ...; do
sudo /opt/ABBYYOCR9/abbyyocr9 ... -if $f ... -of $f.new
touch -r $f $f.new
mv $f.new $f
done
IFS=$(echo -en "\n\b")
Como você está assumindo um shell com echo -e
e, de qualquer maneira, você tem o bash em sua linha shebang, você pode usar IFS=$'\n\b'
. Fazendo backspace um separador é bastante estranho. Você não precisa de IFS
para o que está fazendo de qualquer maneira.
OLDIFS=$IFS
…IFS=$OLDIFS
Observe que isso restaura o valor antigo de IFS
apenas se IFS
foi definido inicialmente. Se IFS
foi inicialmente desfeito, isso define IFS
como a string vazia, o que é completamente diferente. Em ksh, bash ou zsh, se você precisar definir IFS
temporariamente, poderá escrever seu código em uma função e tornar IFS
local nessa função. Em outros shells, você precisa ter cuidado com o caso não definido.
'find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"'
Nunca use a substituição de comando na saída de find
.
$IFS
. Se você definir IFS
para uma nova linha, isso dividirá a saída em novas linhas, mas você ainda não poderá manipular nomes de arquivos que contenham novas linhas. A[12].pdf
, A1.pdf
e A2.pdf
, você acabará com A1.pdf A2.pdf A1.pdf A2.pdf
. Você pode desativar globbing com set -f
(e voltar com set +f
), mas aqui (como na maioria das vezes) o caminho certo é não usar a substituição de comandos. Use o argumento -exec
para find
(ou se o seu sistema tiver -print0
, você pode usar find … -print0 | xargs -0 …
; isso é útil apenas para atuar em vários arquivos de uma vez se você precisar de portabilidade para antigos sistemas Linux ou sistemas atuais do OpenBSD que possuem -print0
mas não -exec … {} +
).
ORIGTS='stat -c "%Y" $f' # [transform $f] touch -t $ORIGTS $f
Observe que você está perdendo aspas duplas em torno de $f
(elas não são necessárias se esses forem os resultados da divisão e você não tiver alterado IFS
desde então e a globbing estiver desativada, mas, na verdade, sempre aspas duplas, a menos que você saiba por que não pode deixá-las ativadas).
Isso é desajeitado e não portátil ( stat
não existe em todos os sistemas e seus argumentos são diferentes nos diferentes sistemas em que ele existe). touch
tem uma opção portátil para definir um arquivo para o registro de data e hora de outro arquivo: touch -r REFERENCE_FILE FILE
. Eu recomendaria uma de duas abordagens:
touch -r
para definir a data do novo arquivo e, finalmente, mova o novo arquivo para o lugar. É melhor ter certeza de que a saída está boa antes que algo aconteça com a entrada; caso contrário, se a transformação for interrompida por algum motivo (por exemplo, uma falha de energia), você perderá dados. touch -r
duas vezes: uma vez para salvar a data do arquivo original em um arquivo temporário vazio (que será criado automaticamente), depois novamente a transformação para restaurar a data usando o arquivo temporário. Assim:
find /mnt/library/Libra/Libra/Ashfords -name '*.pdf' \
-exec sh -c 'transform "$0" to "$0.tmp" && touch -r "$0" "$0.tmp" && mv -f "$0.tmp" "$0"' {} \;
Por algum motivo, perdi a resposta sobre touch -r
; se por algum motivo estranho você não tiver o stat
do GNU coreutils como na resposta aceita nem pode usar touch -r
, aqui está como obter o timestamp no formato touch
-friendly com um stat
do tipo BSD.
% /usr/bin/stat -f '%Sm' johnson
Oct 23 22:51:00 2012
% /usr/bin/stat -t '%Y%m%d%H%M.%S' -f '%Sm' johnson
201210232251.00
% touch foo
% touch -t $(/usr/bin/stat -t '%Y%m%d%H%M.%S' -f '%Sm' johnson) foo
% /usr/bin/stat -f '%Sm' foo
Oct 23 22:51:00 2012
Mas, na verdade, use apenas touch -r
:
% touch foo
% touch -r johnson foo
% /usr/bin/stat -f '%Sm' foo
Oct 23 22:51:00 2012