Estou tentando OCR alguns documentos insitu (a partir de uma linha de comando Linux em um compartilhamento do Windows). O processo de OCR é encontrado e eu confundi usando o comando find para canalizar os arquivos pelo loop corretamente.
No entanto, preciso preservar o registro de data e hora original para modificado. Atualmente, estou tentando usar o stat e tocar como 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 touch falha. executando os comandos separadamente, notei que "stat -c" é algo parecido com isto:
1334758696
que é como nenhum encontro que eu conheço. Sinto como se estivesse perto, mas não consigo descobrir como converter a data que tenho em uma versão amigável ao toque. É alguma forma de segundos de alguma coisa?
IFS
parece incomum. Deseja realmente dividir em backspace (\b
)? Veja unix.stackexchange.com/questions/9496/… para obter algumas dicas.Respostas:
stat's
output é um registro de data e hora do Unix, também chamado de segundos desde a época .Todos os coreutils GNU que aceitam uma data permitem que você coloque um carimbo de data / hora, prefixando-o com um
@
.Então tente isso
Veja coreutils - Segundos desde a época
fonte
touch
pode usar o carimbo de data e hora de um arquivo usando a-r
opção Você pode enviar para um arquivo diferente (suponho abaixo que-if
seja um arquivo de entrada e-of
seja um arquivo de saída)fonte
stat
.Desde que você está assumindo um shell com
echo -e
, e você tem bash na sua linha shebang de qualquer maneira, você pode usá-loIFS=$'\n\b'
. Tornar o backspace um separador é bastante estranho. Você não precisaIFS
do que está fazendo de qualquer maneira.Observe que isso restaura o valor antigo de
IFS
apenas seIFS
foi definido inicialmente. SeIFS
inicialmente não foi definido, isso defineIFS
a sequência vazia, que é completamente diferente. No ksh, bash ou zsh, se você precisar configurarIFS
temporariamente, poderá escrever seu código em uma função e tornarIFS
local essa função. Em outras conchas, você precisa ter cuidado com o caso não definido.Nunca use substituição de comando na saída de
find
.$IFS
. Se você definirIFS
uma nova linha, isso dividirá a saída em novas linhas, mas você ainda não poderá lidar com nomes de arquivos que contenham novas linhas.A[12].pdf
,A1.pdf
eA2.pdf
, você vai acabar comA1.pdf A2.pdf A1.pdf A2.pdf
. Você pode desativar o globbing comset -f
(e voltarset +f
a usar com ), mas aqui (como na maioria das vezes) o caminho certo é não usar a substituição de comando.Use o
-exec
argumento parafind
(ou, se o seu sistema tiver-print0
, você pode usá-lofind … -print0 | xargs -0 …
; isso só é útil para atuar em vários arquivos de uma só vez, se você precisar de portabilidade para sistemas Linux antigos ou sistemas OpenBSD atuais que ainda-print0
não possuem-exec … {} +
).Observe que faltam aspas duplas
$f
(elas não são necessárias se estes são os resultados da divisão e você não mudouIFS
desde então e o globbing está desativado, mas, na verdade, sempre coloque aspas duplas, a menos que você saiba por que pode ' não os deixe ligados).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 existe).touch
tem uma opção portátil para definir um arquivo para o timestamp de outro arquivo:touch -r REFERENCE_FILE FILE
. Eu recomendaria uma das duas abordagens:touch -r
para definir a data do novo arquivo e, finalmente, mova o novo arquivo para o local. É melhor garantir que a saída esteja correta antes que algo aconteça na entrada; caso contrário, se a transformação for interrompida por qualquer motivo (por exemplo, falta 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) e depois após a transformação para restaurar a data usando o arquivo temporário.Portanto:
fonte
Por alguma razão, perdi a resposta sobre
touch -r
; se, por algum motivo estranho, você não tiver o GNU coreutils 'stat
como na resposta aceita, nem puder usartouch -r
, aqui está como obter o carimbo de data / hora notouch
formato amigável com um BSD-likestat
.Mas realmente, basta usar
touch -r
:fonte
Eu tive o mesmo problema, vindo do processo de 'criação de filmes'.
No exemplo abaixo
orig_file.wav
está o arquivo com registro de data e hora original, enquantoprocessed_file.wav
o arquivo com o mesmo conteúdo, mas com registro de data e hora incorreto.ANTES:
localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav
O COMANDO:
localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav
DEPOIS DE:
localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav
NOTAS:
stat
em ticks invertidos fornece o registro de data e hora de criação do arquivo original como tempo de época unix (em segundos). O @ do coreutils o converte em uma data iso quedate
pode entender e reformatar com YYYYMMDDHHmm.SS para que eletouch
possa entendê-lo. Coloquei odate
comando em $ (), como um equivalente a ticks invertidos, pois eles não podem ser reutilizados no mesmo comando.fonte
touch -r
)? (2)stat
pode ser colocado$(…)
; eles podem ser usados várias vezes em um comando.