dokunmak için zaman damgası sağlamak için stat kullanma


11

Bazı belgeler insitu (bir windows paylaşımında bir linux komut satırından) OCR çalışıyorum. OCRing işlemi bulmak ve ben döngü aracılığıyla dosyaları doğru boru için find komutunu kullanarak karışmış.

Ancak değiştirilmeleri için orijinal zaman damgasını korumam gerekiyor. Şu anda stat ve touch'ı aşağıdaki gibi kullanmaya çalışıyorum:

#!/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

Tabii ki dokunmatik komut başarısız. komutları ayrı ayrı çalışan "stat -c" bu satırları boyunca bir şey olduğunu fark:

1334758696

ki hiçbir tarih bilmiyorum. Sanki yakınım gibi hissediyorum ama içinde bulunduğum tarihi dokunmatik bir sürüme nasıl dönüştüreceğimizi anlayamıyorum. Bir şeyden saniyeler mi?


Bir yana: kullanımınız IFSolağandışı görünüyor. Gerçekten backspace ( \b) üzerinde bölmek istediniz mi ? Bazı ipuçları için unix.stackexchange.com/questions/9496/… adresine bakın .
Mikel

Yanıtlar:


17

stat'soutput, Epoch'tan bu yana saniye olarak da adlandırılan bir Unix zaman damgasıdır .

Bir tarihi kabul eden tüm GNU coreutils, zaman damgasının önüne bir ön ek koyarak bir zaman damgası koymanıza izin verir @.

Öyleyse dene

touch -d @$ORIGTS $f

Coreutils'e bakın - Dönemden bu yana geçen saniye


ah, şimdi linux'da gördüğüm birçok zaman damgasını açıklıyor! Çok teşekkürler
Tim Alexander

8

touch-rseçeneğini kullanarak bir dosyanın zaman damgasını kullanabilir . Farklı bir dosyaya çıktı almak isteyebilirsiniz (aşağıda -ifgirdi dosyası ve -ofçıktı dosyası olduğunu varsayıyorum )

for f in ...; do
    sudo /opt/ABBYYOCR9/abbyyocr9 ... -if $f ... -of $f.new
    touch -r $f $f.new
    mv $f.new $f
done

Kaçınmak için +1 stat.
l0b0

3

IFS=$(echo -en "\n\b")

Bir kabuk olduğunu varsaydığınız echo -eve yine de shebang hattınızda bash yaptığınız için kullanabilirsiniz IFS=$'\n\b'. Geri tuşu ayırıcı yapmak oldukça tuhaf. IFSZaten yaptığın şeye ihtiyacın yok .

OLDIFS=$IFS
...
IFS=$OLDIFS

Bunun IFSyalnızca IFSbaşlangıçta ayarlanmışsa eski değerini geri yüklediğini unutmayın . Eğer IFS, bu setler başlangıçta tanımsız oldu IFStamamen farklı boş bir dize, için. Ksh, bash veya zsh'de, IFSgeçici olarak ayarlamanız gerekirse , kodunuzu bir işleve yazabilir ve IFSbu işleve yerel yapabilirsiniz . Diğer mermilerde, ayarlanmamış kasaya dikkat etmelisiniz.

`find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"`

Çıkışında komut yerine kullanmayın find.

  • Bu, çıktıyı içindeki karakterlere böler $IFS. Yeni IFSbir satıra ayarlarsanız , çıkış yeni satırlara ayrılır, ancak yeni satır içeren dosya adlarını işleyemezsiniz.
  • Komut ikamesinin sonucu kelimelere bölünmekle kalmaz, aynı zamanda her kelime bir glob paterni olarak kullanılır. Aradığınız bulunursa A[12].pdf, A1.pdfve A2.pdf, sen ile bitireceğiz A1.pdf A2.pdf A1.pdf A2.pdf. Globbing'i ile kapatabilirsiniz set -f(ve tekrar açabilirsiniz set +f), ancak burada (çoğu zaman olduğu gibi) doğru yol komut yerine koymayı kullanmamaktır.

Kullanım -execiçin argüman find(sistem varsa ya -print0kullanabileceğiniz find … -print0 | xargs -0 …yerine, bu sahip olduğunuz eski Linux sistemleri veya geçerli OpenBSD sistemlerine taşınabilirlik gerekiyorsa Aynı anda birden fazla dosya üzerinde işlem yapılması yararlıdır -print0ama -exec … {} +).

ORIGTS=`stat -c "%Y" $f`
# [transform $f]
touch -t $ORIGTS $f

Etrafta çift tırnak işareti eksik olduğunu unutmayın $f(bunlar bölme sonuçlarıysa ve o IFSzamandan beri değişmediyseniz buna gerek yoktur ve globbing kapalıdır, ancak gerçekten, neden yapabileceğinizi bilmiyorsanız her zaman çift tırnak işareti koyun ' Onları açık bırakmayın).

Bu beceriksiz ve taşınabilir statdeğildir ( tüm sistemlerde mevcut değildir ve argümanları var olduğu farklı sistemlerde farklıdır). touchBaşka bir dosyanın zaman damgasına bir dosyayı ayarlamak için taşınabilir bir seçeneği vardır: touch -r REFERENCE_FILE FILE. Bunun yerine iki yaklaşımdan birini öneriyorum:

  • Yapabiliyorsanız, önce orijinal dosyayı yeni bir dosyaya dönüştürün, ardından yeni dosyanın touch -rtarihini ayarlamak için arayın ve son olarak yeni dosyayı yerine taşıyın. Girdiye bir şey gelmeden önce çıktının iyi olduğundan emin olmak daha iyidir; aksi halde, dönüşüm herhangi bir nedenle kesilirse (örn. elektrik kesintisi), veri kaybedersiniz.
  • Dönüşüm üzerinde kontrol sahibi olmadığınız bir kara kutu ise, touch -riki kez kullanabilirsiniz : orijinal dosyanın tarihini boş bir geçici dosyaya (otomatik olarak oluşturulacak) kaydetmek için bir kez, daha sonra tarihi geri yüklemek için dönüşümden sonra tekrar geçici dosyayı kullanarak.

Böylece:

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"' {} \;

0

Nedense hakkında cevabı kaçırdım touch -r; garip bir nedenden dolayı ne GNU coreutils'iniz statkabul edilen cevapta olduğu gibi ne de kullanabiliyorsanız touch -r, zaman damgasını touchBSD benzeri bir şekilde arkadaşça formatta nasıl elde edeceğiniz aşağıda açıklanmıştır stat.

% /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

Ama gerçekten, sadece şunu kullanın touch -r:

% touch foo
% touch -r johnson foo
% /usr/bin/stat -f '%Sm' foo
Oct 23 22:51:00 2012

0

Aynı sorunu yaşadım 'film yapımı' süreçlerinden.

Aşağıdaki örnekte orig_file.wavorijinal zaman damgasına processed_file.wavsahip dosya, aynı içeriğe sahip dosya ancak yanlış zaman damgasına sahip.

ÖNCE:

localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav

KOMUTA:

localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav

SONRA:

localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav

NOTLAR:

statters keneler size orijinal dosyanın unix çağırma süresi (saniye cinsinden) oluşturma zaman damgasını verir. Coreutils'den @, onu dateanlayabilmesi için YYYYMMDDHHmm.SS'yi anlayabilen ve yeniden biçimlendirebilen bir iso tarihine dönüştürür touch. dateKomutu, aynı komutta tekrar kullanılamayacağından, ters kenelerin eşdeğeri olarak $ () içine koydum .


(1) Bu, Nicholas Riley'nin cevabı ile neredeyse tamamen aynı gibi görünüyor, ancak daha karmaşık. Neden kimse bundan ziyade bunu kullanmak isteyesin (ya da daha iyisi glenn jackman'ın cevabını kullanarak touch -r)? (2)  stat konabilir $(…); bir komutta birden çok kez kullanılabilirler.
G-Man

Zaman yaratmak yerine değişiklik zamanını kullanarak verdiği cevaptan başka, doğru gibi görünüyorsunuz. Bu cevabı fark etmedim. Benimkini aşağı oylayabilirsiniz.
dominikz

Bana sorarsan, hiç eğlenceli değil. :-) ⁠
G-Man, '
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.