नवीनतम फ़ाइल को संशोधित तिथि द्वारा खोजें


38

यदि मैं (बड़ी) निर्देशिका में उपनिर्देशिका वाली नवीनतम फ़ाइल (माइम) को खोजना चाहता हूं, तो मैं यह कैसे करूंगा?

बहुत सी पोस्ट में मैंने पाया है कि कुछ भिन्नताएँ हैं ls -lt | head(आश्चर्यजनक रूप से, कई सुझाव ls -ltr | tailजो एक ही है लेकिन कम कुशल है) जो तब तक ठीक है जब तक आपके पास उपनिर्देशिका (I do) नहीं है।

तो फिर, आप कर सकते हैं

find . -type f -exec ls -lt \{\} \+ | head

जो निश्चित रूप से एक कमांड द्वारा निर्दिष्ट की जा सकने वाली अधिक फ़ाइलों के लिए ट्रिक करेगा, यानी यदि आपके पास एक बड़ी निर्देशिका है, -exec...\+तो अलग कमांड जारी करेगा; इसलिए प्रत्येक समूह को lsअपने भीतर ही सुलझा लिया जाएगा लेकिन कुल सेट पर नहीं; इसलिए मुखिया पहले बैच की अंतिम प्रविष्टि उठाएगा।

कोई जवाब?


btw, आप उन सभी backslashes में से कोई भी जरूरत नहीं है।
enzotib

@enzotib: आप ( \ + ) करते हैं, अन्यथा आप प्राप्त करते हैंfind: missing argument to '-exec'
व्यवस्थित करें

@ व्यवस्था: मेरे पास यह त्रुटि नहीं है, क्योंकि +इसका कोई अर्थ नहीं है bash, इसलिए इसे भागने की कोई आवश्यकता नहीं है।
enzotib

@enzotib: आप सही हैं, मेरी गलती है, क्षमा करें
व्यवस्थित करें

जवाबों:


46

आपको बाहरी कमांड (के रूप में ls) पुनरावृत्ति करने की आवश्यकता नहीं है, क्योंकि findआपको -printfकार्रवाई के माध्यम से सभी की आवश्यकता हो सकती है:

find /path -printf '%T+ %p\n' | sort -r | head

1
हाँ, मैं साथ आया था find . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1लेकिन आपका समाधान बहुत साफ है!
रिच

3
संलग्न | cut -d ' ' -f2फ़ाइल नाम प्राप्त करने का एकमात्र
qwr

आप headएक निश्चित संख्या में लाइनों को शामिल करने के आउटपुट को भी कम कर सकते हैं । मुझे केवल पहली पंक्ति की आवश्यकता थी, इसलिए मैंने इस्तेमाल कियाhead -n 1
तिमाह

8

मुझे आज भी ऐसी ही समस्या थी, लेकिन मैंने उस पर हमला किया find। मुझे sshअपने घर की निर्देशिका में सबसे हाल ही में संपादित की गई फ़ाइल को वापस करने के लिए कम से कम चलाने की आवश्यकता थी । यह मोटे तौर पर मेरे साथ आया था:

ls -tp | grep -v /$ | head -1

निर्देशिकाओं में एक अनुगामी स्लैश जोड़ने का -pविकल्प ls, grep -vएक स्लैश (उर्फ, सभी निर्देशिकाओं) में समाप्त होने वाली लाइनों को हटाता है, और head -1आउटपुट को एक फ़ाइल में सीमित करता है।

यह बहुत कम वर्बोज़ का उपयोग करने से है findअगर आप सभी वापसी करना चाहते हैं फ़ाइल का नाम है।


यह उपनिर्देशिका नहीं संभालती है।
क्लेमेंट

4

यह मेरे सिस्टम से तेज है printf, हालांकि मुझे समझ नहीं आता कि क्यों

find /path -type f -exec stat -c "%y %n" {} + | sort -r | head

मैं पुष्टि करता हूं, तेज है।
enzotib

एक और बात, ... | sort -r | head -n1 | cut -d " " -f 4-अगर आप केवल फ़ाइल नाम प्राप्त करना चाहते हैं।
林果 林果

मैं सिर्फ sort -rगलत पाया अगर कई लाइनों में फ़ाइल नाम मौजूद होगा।
林果 林果

2

संपादित करें: मुझे लगता है कि यह पोस्ट 'विशेष रूप से उपयोगी नहीं है' जैसा कि मैंने सोचा था कि यह था। यह वास्तव में तेज़ समाधान है जो अभी हाल ही में संशोधित फ़ाइल (फ़ाइलों की पूरी सूची को सॉर्ट करने के बजाय) का ट्रैक रखता है:

find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '

स्पष्टता के लिए कई लाइनों में फैला हुआ यह निम्नानुसार है:

find . -type f -printf '%T@ %p\n' | awk '
    BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; }
    {
        if ($1 > mostrecenttime)
            { mostrecenttime = $1; mostrecentline = $0; }
    }
    END { print mostrecentline; }' | cut -f2- -d ' '

EDIT का अंत


विशेष रूप से उपयोगी पोस्ट नहीं, लेकिन चूंकि 'व्यवस्था' गति पर चर्चा कर रही थी, मैंने सोचा कि मैं इसे साझा करूंगा।

अरेंजमेंट और एनज़ोटिब के सॉल्यूशंस में डायरेक्टरी के अंदर मौजूद सभी फाइलों को उनके mtimes के साथ सूचीबद्ध करना और फिर छांटना शामिल है। जैसा कि आप जानते हैं कि अधिकतम खोजने के लिए छंटाई आवश्यक नहीं है। अधिकतम ढूँढना रेखीय समय में किया जा सकता है लेकिन छँटाई में n लॉग (n) समय लगता है [मुझे पता है कि अंतर बहुत अधिक नहीं है, लेकिन फिर भी।)] मैं इसे लागू करने का एक साफ तरीका नहीं सोच सकता। [संपादित करें: एक साफ-सुथरी (जो गंदी दिख रही है) और ऊपर प्रदान किया गया तेज़ कार्यान्वयन।]

अगली सबसे अच्छी बात - एक निर्देशिका में सबसे हाल ही में संपादित फ़ाइल को खोजने के लिए, प्रत्येक स्तर 1 उपनिर्देशिका में सबसे हाल ही में संपादित की गई फ़ाइल को पुन: प्राप्त करें। इस फ़ाइल को उपनिर्देशिका का प्रतिनिधित्व करते हैं। अब स्तर 1 फाइलों को स्तर 1 उपनिर्देशिकाओं के प्रतिनिधियों के साथ क्रमबद्ध करें। यदि प्रत्येक निर्देशिका की स्तर 1 फ़ाइलों और उप-डायरियों की संख्या लगभग एक स्थिर है, तो इस प्रक्रिया को कुल फ़ाइलों की संख्या के साथ रैखिक रूप से स्केल करना चाहिए।

इसे लागू करने के लिए मैं आया हूं:

findrecent() { { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; }
findrecent .

मैंने इसे चलाया और find: findrecent: No such file or directoryत्रुटियों का एक गुच्छा मिला । कारण: -एक अलग शेल में खोज का रन। मैंने .bashrc, .xsessionrc में खोजक को परिभाषित करने की कोशिश की, लेकिन इनसे मदद नहीं मिली [मैं यहाँ मदद की सराहना करूँगा]। अंत में मैंने डालने का सहारा लिया

#!/bin/bash
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

एक स्क्रिप्ट findrecentमें मेरे पेट में कहा जाता है और फिर इसे चला रहा है।

मैंने इसे चलाया, बिना किसी आउटपुट के इंतजार और इंतजार करता रहा। बस मुझे यकीन है कि मैं किसी भी अनंत छोरों के साथ काम नहीं कर रहा था, मैंने फ़ाइल को संशोधित किया

#!/bin/bash
echo "$1" >&2
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

और फिर से कोशिश की। इसने काम तो किया - लेकिन मेरे होम-फोल्डर पर 1 मिनट 35 सेकेंड का समय लगा - अरेंजमेंट और एनज़ोटिब के समाधान में क्रमशः 1.69, 1.30 सेकंड का समय लगा!

O (n) की श्रेष्ठता O (n लॉग (n)) के लिए बहुत कुछ! धिक्कार है आप कॉल ओवरहेड को काम करते हैं! [या बल्कि स्क्रिप्ट कॉल ओवरहेड]

लेकिन यह स्क्रिप्ट पहले के समाधानों की तुलना में बेहतर है और मुझे यकीन है कि यह Google के मेमोरी बैंक की तुलना में उनके मुकाबले अधिक तेजी से चलेगा


2

के perlसाथ संयोजन के रूप में उपयोग करें find:

 find my_directory -type f -printf '%T@\t%p\n' | perl -ane '@m=@F if ($F[0]>$m[0]); END{print $m[1];}'

आपको फ़ाइल का नाम सबसे बड़ी अवधि == अंतिम फ़ाइल के साथ संशोधित किया गया है।


1

यह लगभग फैशनेबल नहीं है, लेकिन मध्यरात्रि कमांडर के साथ इसे हासिल करना भी संभव है : * के लिए खोज, परिणाम को पैनलबद्ध करें, रिवर्स ऑर्डर में संशोधन समय के अनुसार।

जाहिर है, यह थोड़ा धीमा है find- मेरे घर की निर्देशिका, जिसमें 922000 फाइलें हैं, को mcलगभग 14 मिनट में find5 से कम खर्च किया गया था - लेकिन कुछ लाभ हैं:

  • मैं शायद लंबा समय बिताता हूँ, 9 मिनट का अंतर एक उचित खोज मंगलाचरण का आविष्कार करता है :)

  • त्रुटि का कम मौका (निर्दिष्ट करने के लिए भूल जाओ -आर आदि के लिए - फिर से शुरू करें)

  • फ़ाइलों को फिर से क्वेरी किए बिना - सॉर्ट ऑर्डर आदि को बदलते हुए परिणाम के साथ खेलना संभव है।

  • परिणाम सेट से केवल कुछ फ़ाइलों पर फ़ाइल संचालन करना संभव है - अर्थात आकार के आधार पर, कुछ बड़ी फ़ाइलों को हटा दें जिनकी आवश्यकता नहीं है

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