"खोज" का उपयोग करके दो तिथियों के बीच फाइलें कैसे खोजें?


21

मेरे पास एक ईमेल खाता है जो 60GB ईमेल पास कर चुका है, और वर्तमान में मुझे ईमेल क्लाइंट को पिछले साल (2011) के ईमेल संग्रह का उपयोग करने में बहुत परेशानी हो रही है।

वाया टर्मिनल, मैं 2011-01-01 और 2011-12-31 के बीच फाइलों का पता लगाने के लिए उपयोग करने की कोशिश कर रहा हूं , लेकिन कोई फायदा नहीं हुआ।

मैं दो तिथियों के बीच फाइलें कैसे पा सकता हूं?

यदि प्रासंगिक है, तो अंतिम लक्ष्य एक बैच होगा जो एक फ़ोल्डर में, तिथि अंतराल को मिलाते हुए प्रत्येक फ़ाइल को स्थानांतरित करेगा।


@EliahKagan उस समय, यदि स्मृति कार्य करती है, तो डुप्लिकेट किए गए नाम कोई समस्या नहीं थी। फिर भी, यदि आप फ़ीड करते हैं कि आपके पास समय है, तो किसी भी विषय पर अतिरिक्त जानकारी की हमेशा सराहना की जाती है :) इसके अलावा, मैंने आपके उत्तर पर मतदान किया है क्योंकि यह इस विषय पर अतिरिक्त जानकारी प्रदान करता है।
ज़ूलुल

@ एलियाकगन उस मामले में, मैं आपको उस व्यावहारिक असफल-सुरक्षित के साथ एक उत्तर प्रदान करने के लिए प्रोत्साहित करता हूं, जिसे आपने हाइलाइट किया है :)
Zuul

जवाबों:


16

आप इस स्क्रिप्ट का उपयोग कर सकते हैं:

#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
  mv $i /moved_emails_dir/
done

6
आउटपुट को findशेल forलूप में इस तरह संसाधित नहीं किया जाना चाहिए , सिवाय इसके कि जब यह गारंटी दी जाए कि किसी भी फाइल के नाम में कोई रिक्त स्थान नहीं है। -exec, -execdirया -print0 | xargsआमतौर पर इसके बजाय इस्तेमाल किया जाना चाहिए; एक अन्य संभावित समाधान, जो आमतौर पर बहुत कम वांछनीय होता है, लेकिन एक forलूप का उपयोग करने की अनुमति देता है , अस्थायी रूप से सेट करने के लिए है IFSताकि अंतरिक्ष को क्षेत्र विभाजक के रूप में पहचाना न जाए।
एलिया कगन

@ EliahKagan तो कमांड क्या दिखेगी: बस के findसाथ बदलें exec? क्या आप एक उत्तर जोड़ना चाहेंगे जो रिक्त स्थान के उपयोग को संबोधित करे .. ?? बहुत सराहना की।
शेरलहोमन

3
@ शेरिलहोमन नहीं, execकमांड का उपयोग न करें । चलाने के findलिए -execकार्रवाई के साथ एक कमांड का उपयोग करें mv, या जो कुछ भी आपको चलाने की आवश्यकता है, जैसा कि मैंने पोस्ट किया जवाब में वर्णित है । जब find... -execयह पाया गया pathnames के साथ आपकी कमांड चलाता है, तो यह एक शेल का उपयोग नहीं करता है, इसलिए रिक्त स्थान शब्द विभाजन या ग्लोबिंग को ट्रिगर नहीं करते हैं । (आप अपने विशिष्ट मामले के बारे में एक नया प्रश्न पोस्ट करना चाहते हैं, या वास्तव में आप जो जानना चाहते हैं उससे पूछ सकते हैं।)
एलियाह कगन

@EliahKagan क्षमा करें, मैंने आपकी पोस्ट को गलत बताया - और यह आप से था ! तुम कमाल हो! आपकी पोस्ट बहुत बढ़िया है .. और जवाब देने के लिए धन्यवाद, भले ही यह पढ़ने में मेरी अपनी त्रुटि थी !!
शेरिल्होमन

40

बैश को दो तिथियों के बीच फाइलें मिलें:

find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08

उन फ़ाइलों की सूची लौटाता है जिनमें 2010-10-07 और 2014-10-08 से पहले टाइमस्टैम्प हैं

बैश को 15 मिनट पहले से अब तक की फाइलें खोजें:

find . -type f -mmin -15

15 मिनट पहले लेकिन अब से पहले टाइमस्टैम्प वाली फ़ाइलों की सूची लौटाता है।

बैश दो टाइमस्टैम्प के बीच फाइल खोजें:

find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"

के बीच 2014-10-08 10:17:00और टाइमस्टैम्प के साथ फाइल लौटाता है2014-10-08 10:53:00


10

डुप्लिकेट नाम होने पर फ़ाइलों को ले जाना और उपयोगकर्ता को संकेत देना:

जैसा कि Subv3rsion और एरिक लेसचिंस्की के उत्तर दिखाते हैं, -newermtविधेय इसके संचालन के रूप में निर्दिष्ट तिथि (और वैकल्पिक समय) की तुलना में हाल ही में संशोधित फ़ाइलों का चयन करता है। फाइलें खोजने के लिए

  • कहीं भी srcdir(जैसे, इसके उपनिर्देशिका, उनके उपनिर्देशिका, आदि सहित)
  • अंतिम बार (उदाहरण के लिए) सितंबर 2014 में संशोधित किया गया
  • और उन्हें स्थानांतरित करने के लिएdestdir

...तुम दौड़ सकते हो:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;

एक -execअभिव्यक्ति में, फाइंड नाम के स्थान पर पाया जाने वाला फ़ाइल नाम गुजरता है {};यह दर्शाता है -execकि कमांड को चलाने के लिए, और उसके तर्क, सभी प्रदान किए गए हैं (यदि बाद के भाव उस विशेष -execविधेय के तर्कों के बाद खोजने के लिए पारित किए जाते हैं - इसका एक उदाहरण के लिए नीचे देखें)। ;बच जाना चाहिए क्योंकि \;यह विशेष रूप से खोल द्वारा व्याख्या नहीं की गई है। (बिना \, ;पूरी findकमांड को समाप्त करने के लिए , एक नई लाइन के समान काम करेगा। भले ही इस findकमांड के पास इस -execअभिव्यक्ति के बाद कुछ भी नहीं है , ;तर्क पारित करने में विफल अभी भी एक सिंटैक्स त्रुटि है।)

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

mv -i किसी भी समय गंतव्य पर किसी फ़ाइल को ओवरराइट कर दिया जाएगा, जैसे कि यदि होगा तो संकेत देता है:

  • एक ही नाम की एक फ़ाइल पिछले बैकअप से मौजूद है, या
  • एक ही नाम की एक फ़ाइल लेकिन एक srcdirही findऑपरेशन के दौरान पहले से ही स्थानांतरित की गई एक अलग उपनिर्देशिका से , या
  • (कम से कम संभावना) एक ही नाम की एक फ़ाइल srcdirउसी findऑपरेशन के दौरान कहीं बनाई गई थी , मूल स्थानांतरित होने के बाद लेकिन जल्द ही findएक अलग उपनिर्देशिका का पता लगाने के लिए पर्याप्त है ।

आह्वान करने के अन्य तरीके rm:

आपके पास डुप्लिकेट नामों वाली फ़ाइलों को संभालने के लिए अन्य विकल्प हैं।

  • बिना -i(यानी ), आमतौर पर अनुमोदन के लिए संकेत नहीं दिया जाएगा, लेकिन ऐसा तब होगा जब गंतव्य फ़ाइल केवल-पढ़ने के लिए थी। ( कभी-कभी किसी रीड-ओनली फ़ाइल को अधिलेखित करने में भी सफल हो सकते हैं, जैसे कि उपयोगकर्ता जो इसे चला रहा है वह फ़ाइल का मालिक है।)mv {} destdir/mvmv
  • यदि आप अन्तरक्रियाशीलता की उस डिग्री को भी नहीं चाहते हैं, और mvहमेशा चाहते हैं कि पहचान की गई फ़ाइलों को अधिलेखित कर दें, उपयोग करें mv -f
  • यदि, इसके विपरीत, आप स्रोत फ़ाइलों को तब छोड़ना चाहते हैं जब पहले से ही उसी नाम की कोई गंतव्य फ़ाइल हो, तो उपयोग करें mv -n
  • mvस्वीकार करता है -bऔर --backupझंडे स्वचालित रूप से समान नाम फ़ाइलों कि पहले से ही गंतव्य पर मौजूद नाम बदलने के लिए। डिफ़ॉल्ट रूप ~से बैकअप नाम का उत्पादन करने के लिए जोड़ा जाता है, और यदि नाम के साथ एक फ़ाइल और बैकअप नाम के साथ एक फ़ाइल पहले से ही गंतव्य पर मौजूद है, तो बैकअप फ़ाइल अधिलेखित है। इस डिफ़ॉल्ट को इनवॉइस करते समय पारित किए गए विकल्पों mvऔर पर्यावरण चर द्वारा ओवरराइड किया जा सकता है । man mvविवरण के लिए देखें, और नीचे दिए गए उदाहरण।

डुप्लिकेट नामों के मामले में फ़ाइलों को ले जाना और बैकअप बनाना:

सभी फ़ाइलों को स्थानांतरित करने के लिए, एक ~प्रत्यय का उपयोग करके डुप्लिकेट नामों के साथ फ़ाइलों का बैक अप लें , और पहले से मौजूद फाइलें (ताकि कुछ भी अधिलेखित होने से बचने के लिए) के लिए गिने प्रत्यय का उपयोग करें , चलाएं:.~n~.~

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;

यदि आप डुप्लिकेट नामों के साथ फ़ाइलों को छोड़ देते हैं और जानना चाहते हैं कि कौन से हैं:

यदि आप उपयोग करते हैं mv -nऔर यह जानना चाहते हैं कि कौन सी फाइलें स्थानांतरित नहीं हुई थीं क्योंकि उसी नाम के साथ एक और फ़ाइल थी, तो सबसे अच्छा तरीका शायद मूल findकमांड को फिर से चलाने के लिए है , इसके बिना -execऔर इसके दाईं ओर सब कुछ। इससे उनके नाम छपेंगे।
यह आपके द्वारा बनाई गई किसी भी फाइल के नाम को भी प्रिंट करेगा क्योंकि आपने मूल find .... -exec ...कमांड चलाया था , लेकिन इस एप्लिकेशन के लिए आम तौर पर कोई नहीं होगा क्योंकि आप पुराने संशोधन समय वाली फाइलों की तलाश कर रहे हैं। एक फ़ाइल को अपनी वास्तविक उम्र, touchऔर अन्य तंत्रों की तुलना में पुराने टाइमस्टैम्प में बदलना संभव है , लेकिन इस मामले में आपकी जानकारी के बिना होने की संभावना नहीं है।

डुप्लिकेट नामों के कारण फ़ाइलों के रूप में तुरंत जानने की छूट:

mv -nरिपोर्ट नहीं करता है, और न ही कोई विशेष निकास कोड लौटाता है , जब यह किसी फ़ाइल को स्थानांतरित करने से रोकता है। इसलिए यदि आप चाहते हैं कि findरन होते समय आपको तुरंत स्किप की गई फ़ाइलों की सूचना दी जाए , तो आपको उसके लिए एक अलग कदम उठाना होगा। एक तरीका है:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
    -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \; 

कुछ शायद मामूली तकनीकी विचार: यह गलत तरीके से चेतावनी देता है अगर mvयह गंतव्य पर मौजूद किसी भिन्न कारण के लिए फ़ाइल की प्रतिलिपि बनाने में विफल रहता है और रिपोर्टिंग सफलता से बाहर निकलता है । यह असंभव लगता है, लेकिन मुझे यकीन नहीं है कि यह असंभव है। यह संभावित रूप से एक दौड़ की स्थिति भी झेलता है : यह चेतावनी देता है कि जब कोई वास्तविक त्रुटि नहीं होती है, यदि पुरानी फ़ाइल के स्थानांतरित होने के बाद और चेक से पहले उसी नाम की एक नई फ़ाइल उसी स्थान पर बनाई गई थी देखें कि क्या इसे हटा दिया गया था। (आवेदन को ध्यान में रखते हुए, मुझे संदेह है कि या तो समस्या वास्तव में कभी भी होगी।) इससे पहले गंतव्य की जांच करने के लिए इसे फिर से लिखा जा सकता हैइसके बाद फ़ाइल को स्थानांतरित करना: फिर दौड़ की स्थिति स्रोत फ़ाइलों के बजाय नए बनाए गए गंतव्य फ़ाइलों से संबंधित होगी। और जबकि त्रुटियों या चेतावनियों के द्वारा findया mv(या [, हालांकि कोई भी नहीं होना चाहिए) द्वारा रिपोर्ट की गई मानक त्रुटि को लिखा जाएगा , हमारी ...skipped (exists in...चेतावनी मानक आउटपुट के लिए लिखी गई है । आम तौर पर दोनों आपके टर्मिनल पर दिखाई देते हैं, लेकिन अगर आप स्क्रिप्टिंग कर रहे हैं तो यह बात हो सकती है।

मैंने उस कमांड को आसानी से पढ़ने के लिए दो लाइनों पर विभाजित कर दिया है। इसे उस तरह से चलाया जा सकता है, या आप \और नई लाइन (यानी, लाइन ब्रेक) को हटा सकते हैं ।

वह findकमांड कैसे काम करता है ?

findविधेय परीक्षण (जैसे -typeऔर -newermt), उनके वापसी मूल्यों या क्रियाओं (जैसे -printऔर -exec) के लिए उपयोग किया जा सकता है , जो अक्सर उनके दुष्प्रभावों के लिए उपयोग किया जाता है।

कोई ऑपरेटर (जैसे जब -aके लिए और , -oके लिए या ) भाव के बीच आपूर्ति की जाती है, -aनिहित है। शॉर्ट सर्किट मूल्यांकन के लिए और / याfind कार्यरत हैं । (यानी, ) केवल तभी सही है जब p और q दोनों भाव सही हों, इसलिए p के गलत होने पर q का मूल्यांकन नहीं किया जाना चाहिए । यद्यपि हम अक्सर इन शब्दों में नहीं सोचते हैं, यही कारण है कि परीक्षण के बाद के कार्यों या परीक्षणों का मूल्यांकन करने के लिए सही होना चाहिए। उदाहरण के लिए, मान लीजिए कि एक निर्देशिका है। यह असत्य का मूल्यांकन करता है, इसलिए यह बाद में सब कुछ छोड़ सकता है।p qp -a qfind-type f

परीक्षणों की तरह, क्रियाएं भी सही या गलत का मूल्यांकन करती हैं। इस तरह, -execरिपोर्ट यदि निष्पादित कमांड सफलता (सच्ची) या विफलता (झूठी) से बाहर निकल गई। हम इस श्रृंखला -execनिहित के साथ जुड़े हुए भाव और :

-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;

यह फ़ाइल को स्थानांतरित करने का प्रयास करता है, और यदि mvरिपोर्ट विफल हो जाती है, तो रुक जाता है। हम एक सही ढंग से छोड़ दी गई फ़ाइल के बारे में चेतावनी नहीं देना चाहते हैं अगर कुछ अन्य समस्या थी तो इसे स्थानांतरित क्यों नहीं किया गया था।

लेकिन अगर यह सफल रहा, तो यह कमांड चलाता है[ । जैसे find, [तर्कों के रूप में पारित अपनी तरह के भावों का समर्थन करता है। [ -f {} ]चेकों के बाद संकार्य अगर -f(द्वारा इसे पारित कर दिया findके स्थान पर {}) मौजूद है (और एक नियमित फ़ाइल है) या नहीं और फिर सही / सफलता या गलत / विफलता।
(कई कमांड्स के एक्ज़िट स्टेटस की व्याख्या सबसे अच्छी सफलता या असफलता के रूप में की जाती है, लेकिन [मौजूद स्थिति आमतौर पर सबसे अच्छी या सही या सही व्याख्या की जाती है।)

यदि [गलत दिया गया है, तो फ़ाइल चली गई है, इसलिए इसे स्थानांतरित कर दिया गया था, इसलिए कुछ भी करने की आवश्यकता नहीं है। लेकिन अगर [गलत दिया गया है, तो फ़ाइल अभी भी है। फिर findअगली -execअभिव्यक्ति का मूल्यांकन करता है , जो चेतावनी संदेश प्रिंट करता है।

आगे की पढाई


जब मैं समय मिलता है, मैं प्रदर्शन विचार के बारे में और एक अनुभाग जोड़ने की आशा -exec ... +के साथ mv -tकुछ समय जल्द ही,।
एलियाह कगन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.