स्पर्श के लिए टाइमस्टैम्प प्रदान करने के लिए स्टेट का उपयोग करना


11

कुछ दस्तावेज़ों में ओसीआर की कोशिश कर रहा हूँ (एक विंडोज़ शेयर पर एक लाइन कमांड लाइन से)। OCRing की प्रक्रिया है और मैंने लूप के माध्यम से फाइलों को सही ढंग से पाइप करने के लिए फाइंड कमांड का उपयोग करके मैड किया है।

हालांकि मुझे संशोधित करने के लिए मूल टाइमस्टैम्प को संरक्षित करने की आवश्यकता है। मैं वर्तमान में नीचे के रूप में स्टेट और टच का उपयोग करने की कोशिश कर रहा हूं:

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

बेशक टच कमांड फेल है। आज्ञाओं को अलग से चलाने से मुझे लगता है कि "स्टेट-सी" कुछ इस तरह से है:

1334758696

मुझे पता है कि कोई तारीख नहीं है। मुझे ऐसा लगता है कि जैसे मैं पास हूं, लेकिन इस बात को समझ नहीं पाया कि मेरे पास मौजूद तारीख को टच फ्रेंडली वर्जन में कैसे बदला जाए। क्या यह कुछ से कुछ सेकंड का रूप है?


एक तरफ: आपका उपयोग IFSअसामान्य लगता है। क्या आप वास्तव में बैकस्पेस ( \b) पर विभाजित करना चाहते हैं ? कुछ सुझावों के लिए unix.stackexchange.com/questions/9496/… देखें ।
मिकेल

जवाबों:


17

stat'sआउटपुट एक यूनिक्स टाइमस्टैम्प है, जिसे एपोक के बाद सेकंड भी कहा जाता है ।

सभी GNU कोरट्यूट जो एक तारीख को स्वीकार करते हैं, आपको टाइमस्टैम्प को प्रीफ़िक्स करने के बजाय टाइमस्टैम्प लगाने की अनुमति देते हैं @

तो यह कोशिश करो

touch -d @$ORIGTS $f

कोरुटिल्स देखें - युग के बाद के सेकंड


आह कि बहुत सारे टाइमस्टैम्प की व्याख्या करता है जो मैंने अब लिनक्स में देखा है! बहुत बहुत धन्यवाद
टिम अलेक्जेंडर

8

touch-rविकल्प का उपयोग करके फ़ाइल के टाइमस्टैम्प का उपयोग कर सकते हैं । आप किसी भिन्न फ़ाइल में आउटपुट करना चाहते हैं (मेरा मानना ​​है कि -ifइनपुट फ़ाइल है और -ofआउटपुट फ़ाइल है)

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

बचने के लिए +1 stat
l0b0

3

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

जब से आप एक खोल के साथ ग्रहण कर रहे हैं echo -e, और आप वैसे भी अपनी शेबंग लाइन में बैश हैं, आप उपयोग कर सकते हैं IFS=$'\n\b'। बैकस्पेस को एक विभाजक बनाना अजीब है। आप IFSवैसे भी क्या कर रहे हैं के लिए की जरूरत नहीं है।

OLDIFS=$IFS
...
IFS=$OLDIFS

ध्यान दें कि यह IFSकेवल पुराने मूल्य को पुनर्स्थापित करता है यदि IFSशुरू में सेट किया गया था। यदि IFSशुरू में परेशान था, तो यह IFSखाली स्ट्रिंग पर सेट होता है, जो पूरी तरह से अलग है। Ksh, bash या zsh में, यदि आपको IFSअस्थायी रूप से सेट करने की आवश्यकता है, तो आप किसी फ़ंक्शन में अपना कोड लिख सकते हैं और IFSइस फ़ंक्शन को स्थानीय बना सकते हैं । अन्य गोले में, आपको परेशान मामले से सावधान रहने की आवश्यकता है।

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

के आउटपुट पर कमांड प्रतिस्थापन का उपयोग कभी न करें find

  • यह वर्णों में आउटपुट को विभाजित करता है $IFS। यदि आप IFSएक नई पंक्ति में सेट करते हैं, तो यह आउटपुट को नई सीमा में विभाजित करता है, लेकिन आप अभी भी नई नाम वाली फ़ाइल नामों को संभाल नहीं सकते हैं।
  • न केवल आदेश प्रतिस्थापन का परिणाम शब्दों में विभाजित है, बल्कि फिर प्रत्येक शब्द को एक ग्लोब पैटर्न के रूप में उपयोग किया जाता है। यदि आप फ़ाइलें कहते हैं A[12].pdf, A1.pdfऔर A2.pdf, आप के साथ समाप्त हो जाएगा A1.pdf A2.pdf A1.pdf A2.pdf। आप ग्लोबिंग को बंद कर सकते हैं set -f(और साथ में वापस set +f), लेकिन यहां (ज्यादातर समय की तरह) सही तरीका है कमांड प्रतिस्थापन का उपयोग न करना।

-execतर्क का उपयोग करें find(या यदि आपके सिस्टम में है -print0, तो आप find … -print0 | xargs -0 …इसके बजाय उपयोग कर सकते हैं ; यह केवल एक बार में कई फ़ाइलों पर कार्य करने के लिए उपयोगी है, यदि आपको प्राचीन लिनक्स सिस्टम या वर्तमान ओपनबीएसडी सिस्टम की पोर्टेबिलिटी की आवश्यकता है, -print0लेकिन ऐसा नहीं है -exec … {} +)।

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

ध्यान दें कि आप डबल कोट्स को याद कर रहे हैं $f(उन्हें ज़रूरत नहीं है अगर ये विभाजन के परिणाम हैं और आप IFSतब से नहीं बदले हैं और ग्लोबिंग बंद हो गया है, लेकिन वास्तव में, हमेशा दोहरे उद्धरण डालते हैं जब तक कि आपको पता नहीं है कि आप क्यों कर सकते हैं ' t उन्हें छोड़ दो)।

यह अनाड़ी और गैर-पोर्टेबल है ( statसभी प्रणालियों पर मौजूद नहीं है, और इसके तर्क अलग-अलग प्रणालियों में भिन्न हैं जहां यह मौजूद है)। touchफ़ाइल को किसी अन्य फ़ाइल के टाइमस्टैम्प पर सेट करने के लिए एक पोर्टेबल विकल्प है touch -r REFERENCE_FILE FILE:। मैं इसके बजाय दो में से एक दृष्टिकोण की सिफारिश करूंगा:

  • यदि आप कर सकते हैं, तो पहले मूल फ़ाइल को एक नई फ़ाइल में रूपांतरित करें, फिर नई फ़ाइल touch -rकी तारीख निर्धारित करने के लिए कॉल करें , और अंत में नई फ़ाइल को स्थानांतरित करें। यह सुनिश्चित करना बेहतर है कि इनपुट के कुछ होने से पहले आउटपुट ठीक है; अन्यथा, यदि परिवर्तन किसी भी कारण से बाधित है (उदाहरण के लिए एक बिजली की विफलता), तो आप डेटा खो देंगे।
  • यदि परिवर्तन एक ब्लैक बॉक्स है जिस पर आपका कोई नियंत्रण नहीं है, तो आप touch -rदो बार उपयोग कर सकते हैं : एक बार एक खाली अस्थायी फ़ाइल (जो स्वचालित रूप से बनाई जाएगी) पर मूल फ़ाइल की तारीख को बचाने के लिए, फिर परिवर्तन के बाद दिनांक को पुनर्स्थापित करने के लिए अस्थायी फ़ाइल का उपयोग करना।

इस प्रकार:

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

किसी कारण से मैं इस बारे में जवाब देने से चूक गया touch -r; यदि किसी विचित्र कारण से आपके पास न तो GNU कोर्यूटिल्स हैं statजैसा कि स्वीकृत उत्तर में है और न ही उपयोग कर सकते हैं touch -r, तो यहां touchबीएसडी-जैसे के साथ टाइमस्टैम्प इन- फ्रेंडली प्रारूप कैसे प्राप्त करें 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

लेकिन वास्तव में, बस उपयोग करें touch -r:

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

0

मुझे भी यही समस्या थी, 'मूवीमेकिंग' प्रॉक्स 'से आना।

नीचे दिए गए उदाहरण में orig_file.wavमूल टाइमस्टैम्प के साथ फ़ाइल है, जबकि processed_file.wavसमान सामग्री वाली फ़ाइल है, लेकिन गलत टाइमस्टैम्प।

इससे पहले:

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

आदेश:

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

उपरांत:

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

टिप्पणियाँ:

statइनवर्टेड टिक्स आपको मूल फ़ाइल का निर्माण टाइमस्टैम्प यूनिक्स एपोच समय (सेकंड में) के रूप में देता है। Coreutils से @ इसे एक आईएसओ तिथि में परिवर्तित करता है जो dateYYYYMMDDHHmm.SS के साथ समझ और सुधार touchकर सकती है ताकि इसे समझ सकें। मैंने dateकमांड को $ () में डाला , उल्टे टिक्कों के बराबर के रूप में, क्योंकि वे एक ही कमांड में पुन: उपयोग नहीं किए जा सकते हैं।


(1) यह लगभग निकोलस रिले के उत्तर के समान ही लगता है लेकिन अधिक जटिल है। कोई भी इसके बजाय (या, अभी तक, ग्लेन जैकमैन के जवाब का उपयोग करके touch -r) का उपयोग क्यों करना चाहेगा ? (2)  stat में डाला जा सकता है $(…); उन्हें एक कमांड में कई बार इस्तेमाल किया जा सकता है।
जी-मैन का कहना है कि 'मोनिका'

समय के बजाय संशोधन समय का उपयोग करते हुए उनके उत्तर के अलावा, आप सही प्रतीत होते हैं। मैंने इस दूसरे जवाब पर ध्यान नहीं दिया। आप मेरा वोट डाउन कर सकते हैं।
डोमिनिकज़

खैर, अगर आप मुझसे पूछें, तो कोई मज़ा नहीं है। :
जी-मैन ने कहा कि 'मोनिका'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.