menggunakan stat untuk memberikan stempel waktu untuk disentuh


11

Saya mencoba untuk OCR beberapa dokumen insitu (dari baris perintah linux di berbagi windows). Proses OCRing ditemukan dan saya telah kacau menggunakan perintah find untuk mem-pipe file melalui loop dengan benar.

Namun saya perlu mempertahankan cap waktu asli untuk dimodifikasi. Saat ini saya mencoba menggunakan stat dan sentuh seperti di bawah ini:

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

Tentu saja perintah sentuh gagal. menjalankan perintah secara terpisah saya perhatikan "stat -c" adalah sesuatu di sepanjang baris ini:

1334758696

yang seperti tidak ada tanggal yang saya tahu. Saya merasa seolah-olah saya sudah dekat tetapi tidak tahu cara mengubah tanggal yang saya miliki menjadi versi yang ramah sentuhan. Apakah ini beberapa detik dari sesuatu?


Selain: penggunaan Anda IFStampaknya tidak biasa. Apakah Anda benar-benar ingin membagi pada backspace ( \b)? Lihat unix.stackexchange.com/questions/9496/… untuk beberapa tips.
Mikel

Jawaban:


17

stat'soutput adalah cap waktu Unix, juga disebut detik sejak Zaman .

Semua GNU coreutils yang menerima tanggal memungkinkan Anda untuk meletakkan stempel waktu sebagai ganti dengan awalan stempel waktu dengan @.

Jadi coba ini

touch -d @$ORIGTS $f

Lihat coreutils - Detik sejak zaman


ah itu menjelaskan banyak cap waktu yang saya lihat di linux sekarang! Terima kasih banyak
Tim Alexander

8

touchdapat menggunakan stempel waktu file menggunakan -ropsi. Anda mungkin ingin menampilkan ke file yang berbeda (saya berasumsi di bawah -ifini adalah file input dan -offile output)

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

+1 untuk dihindari stat.
l0b0

3

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

Karena Anda mengasumsikan shell dengan echo -e, dan Anda memiliki bash di garis shebang Anda, Anda dapat menggunakannya IFS=$'\n\b'. Membuat backspace pemisah agak aneh. Anda tidak perlu IFSmelakukan apa yang Anda lakukan.

OLDIFS=$IFS
...
IFS=$OLDIFS

Perhatikan bahwa ini mengembalikan nilai lama IFShanya jika IFSawalnya ditetapkan. Jika IFSawalnya tidak disetel, ini diset IFSke string kosong, yang sama sekali berbeda. Di ksh, bash atau zsh, jika Anda perlu mengatur IFSsementara, Anda dapat menulis kode Anda dalam suatu fungsi dan membuat IFSlokal ke fungsi ini. Di shell lain, Anda perlu berhati-hati tentang kasus yang tidak disetel.

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

Jangan pernah menggunakan substitusi perintah pada output dari find.

  • Ini membagi output pada karakter dalam $IFS. Jika Anda mengatur IFSke baris baru, maka ini membagi output di baris baru, tetapi Anda masih tidak bisa menangani nama file yang mengandung baris baru.
  • Tidak hanya hasil substitusi perintah yang dibagi menjadi kata-kata, tetapi kemudian setiap kata digunakan sebagai pola gumpalan. Jika Anda memanggil file A[12].pdf, A1.pdfdan A2.pdf, Anda akan berakhir dengan A1.pdf A2.pdf A1.pdf A2.pdf. Anda dapat mematikan globbing dengan set -f(dan kembali dengan set +f), tetapi di sini (seperti kebanyakan waktu) cara yang tepat adalah tidak menggunakan substitusi perintah.

Gunakan -execargumen untuk find(atau jika sistem Anda memiliki -print0, Anda dapat menggunakan find … -print0 | xargs -0 …sebagai gantinya; ini hanya berguna untuk bertindak pada banyak file sekaligus jika Anda memerlukan portabilitas ke sistem Linux kuno atau sistem OpenBSD saat ini yang memiliki -print0tetapi tidak -exec … {} +).

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

Perhatikan bahwa Anda kehilangan tanda kutip ganda di sekitar $f(mereka tidak diperlukan jika ini adalah hasil pemisahan dan Anda belum berubah IFSsejak saat itu dan globbing dimatikan, tapi sungguh, selalu menempatkan tanda kutip ganda kecuali Anda tahu mengapa Anda bisa ' t biarkan mereka hidup).

Ini kikuk dan non-portabel ( stattidak ada pada semua sistem, dan argumennya berbeda di berbagai sistem di mana ia ada). touchmemiliki opsi portabel untuk mengatur file ke timestamp dari file lain: touch -r REFERENCE_FILE FILE. Saya akan merekomendasikan salah satu dari dua pendekatan:

  • Jika Anda bisa, pertama-tama ubah file asli menjadi file baru, lalu panggil touch -runtuk mengatur tanggal file baru, dan akhirnya pindahkan file baru ke tempatnya. Lebih baik untuk memastikan output baik-baik saja sebelum sesuatu terjadi pada input; jika tidak, jika transformasi terputus karena alasan apa pun (mis. kegagalan daya), Anda akan kehilangan data.
  • Jika transformasi adalah kotak hitam yang tidak dapat Anda kendalikan, Anda dapat menggunakan touch -rdua kali: sekali untuk menyimpan tanggal file asli pada file sementara yang kosong (yang akan dibuat secara otomatis), lalu sekali lagi setelah transformasi untuk mengembalikan tanggal. menggunakan file sementara.

Jadi:

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

Untuk beberapa alasan saya melewatkan jawaban tentang touch -r; jika karena alasan yang aneh Anda tidak memiliki GNU coreutils ' statseperti dalam jawaban yang diterima atau tidak dapat digunakan touch -r, berikut adalah cara untuk mendapatkan cap waktu dalam touchformat ramah dengan BSD-like 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

Tapi sungguh, cukup gunakan touch -r:

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

0

Saya memiliki masalah yang sama, berasal dari proses pembuatan film.

Dalam contoh di bawah orig_file.wavini adalah file dengan cap waktu asli, sedangkan processed_file.wavfile dengan konten yang sama, tetapi cap waktu salah.

SEBELUM:

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

PERINTAH:

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

SETELAH:

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

CATATAN:

statdalam kutu terbalik memberi Anda cap waktu pembuatan file asli sebagai waktu unix epoch (dalam detik). @ Dari coreutils mengubahnya menjadi tanggal iso yang datedapat memahami dan memformat ulang dengan YYYYMMDDHHmm.SS sehingga touchdapat memahaminya. Saya menempatkan dateperintah ke $ (), sebagai yang setara dengan kutu terbalik, karena mereka tidak dapat digunakan kembali dalam perintah yang sama.


(1) Ini tampaknya hampir persis sama dengan jawaban Nicholas Riley tetapi lebih rumit. Mengapa ada orang yang mau menggunakan ini daripada itu (atau, lebih baik lagi, jawaban glenn jackman , menggunakan touch -r)? (2)  stat dapat dimasukkan ke dalam $(…); mereka dapat digunakan beberapa kali dalam satu perintah.
G-Man Mengatakan 'Reinstate Monica'

Selain jawabannya menggunakan waktu modifikasi daripada membuat waktu, Anda tampaknya benar. Saya tidak memperhatikan jawaban lain ini. Anda dapat memilih suara saya.
dominikz

Nah, jika Anda memintaku, itu tidak menyenangkan. :-) ⁠
G-Man Mengatakan 'Reinstate Monica'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.