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


242

ऐसा लगता है कि lsपुनरावर्ती कॉल करते समय फ़ाइलों को सही ढंग से सॉर्ट नहीं करता है:

ls -altR . | head -n 3

मैं एक निर्देशिका में सबसे हाल ही में संशोधित फ़ाइल (उपनिर्देशिका सहित) कैसे पा सकता हूं?


जवाबों:


357
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "

एक विशाल पेड़ के लिए, sortसब कुछ स्मृति में रखना कठिन हो सकता है ।

%T@आपको एक यूनिक्स टाइमस्टैम्प की तरह संशोधन समय देता है, sort -nसंख्यात्मक रूप से, tail -1अंतिम पंक्ति (उच्चतम टाइमस्टैम्प) लेता cut -f2 -d" "है, आउटपुट से पहले फ़ील्ड ( टाइमस्टैम्प) को काट देता है।

संपादित करें: जैसा -printfकि शायद GNU- केवल है, ajreals का उपयोग stat -cभी है। हालांकि बीएसडी पर ऐसा करना संभव है, स्वरूपण के लिए विकल्प अलग हैं ( -f "%m %N"ऐसा प्रतीत होता है)

और मुझे बहुवचन का हिस्सा याद आया; आप और अधिक तो चाहते हैं, तो नवीनतम फ़ाइल, बस पूंछ तर्क तक सामने लाना।


7
यदि आदेश मायने रखता है, तो आप sort -rn | head -3इसके स्थान पर उपयोग स्विच कर सकते हैं sort -n | tail -3। एक संस्करण सबसे पुरानी से नई तक की फाइलें देता है, जबकि दूसरा सबसे पुरानी से नई में जाता है।
डॉन फॉल्कनर

3
मेरे पास एक विशाल निर्देशिका थी (कुछ दस हजार छोटी फाइलें) और मैं प्रदर्शन के बारे में चिंतित था, लेकिन ... यह कमान एक सेकंड से भी कम समय में चलती है! महान, बहुत धन्यवाद !!! :-)
लुकाफ़ेरियो

2
"एक विशाल वृक्ष के लिए, हर चीज़ को स्मृति में रखना कठिन हो सकता है।" sortआवश्यकतानुसार अस्थायी फ़ाइलें (में /tmp) बनाएंगे , इसलिए मुझे नहीं लगता कि यह चिंता का विषय है।
व्लादिमीर पेंटेलेव

1
इसे संशोधित करना: -printf '%T@ %Tb %Td %TY %p\n'आपको एक तारीख मोहर देगा (यदि आवश्यक हो) (समान ls)
bshea

1
मैं निम्नलिखित को कम और अधिक व्याख्यात्मक आउटपुट के साथ find . -type f -printf '%TF %TT %p\n' | sort | tail -1
पाता हूं

129

पर बाद @ plundra का जवाब है, यहाँ बीएसडी और ओएस एक्स संस्करण है:

find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "

1
क्या इसके बजाय BSD / OS X findसमर्थन +करता है \;? क्योंकि वह एक ही काम करता है (कई फाइलों को मापदंडों के रूप में पारित करना), -print0 | xargs -0पाइप के बिना ।
DevSolar

यदि मैं अवरोही क्रम में संशोधित अंतिम 5 या n फ़ाइलों को प्राप्त करना चाहता हूं तो मुझे क्या करना चाहिए?
कुषाण

@ सुखुन बदल जाते head -1हैंhead -5
एमर्सन

20

परिणामों को छांटने और केवल अंतिम संशोधित लोगों को रखने के बजाय, आप awk का उपयोग केवल सबसे बड़े संशोधन समय (यूनिक्स समय में) के साथ प्रिंट करने के लिए कर सकते हैं:

find . -type f -printf "%T@\0%p\0" | awk '
    {
        if ($0>max) {
            max=$0; 
            getline mostrecent
        } else 
            getline
    } 
    END{print mostrecent}' RS='\0'

यह आपकी समस्या को हल करने का एक तेज़ तरीका होना चाहिए यदि फ़ाइलों की संख्या काफी बड़ी है।

मैंने एनयूएल चरित्र (यानी '\ 0') का उपयोग किया है, क्योंकि, सैद्धांतिक रूप से, एक फ़ाइल नाम में कोई भी वर्ण (अंतरिक्ष और नई रेखा सहित) हो सकता है।

यदि आपके पास आपके सिस्टम में ऐसे पैथोलॉजिकल फाइलनेम नहीं हैं, तो आप न्यूलाइन वर्ण का भी उपयोग कर सकते हैं:

find . -type f -printf "%T@\n%p\n" | awk '
    {
        if ($0>max) {
            max=$0; 
            getline mostrecent
        } else 
            getline
    } 
    END{print mostrecent}' RS='\n'

इसके अलावा, यह mawk में भी काम करता है।


यह आसानी से तीन सबसे हाल ही में रखने के लिए अनुकूलित किया जा सकता है।
अगली सूचना तक रोक दिया गया।

1
यह mawkडेबियन मानक विकल्प के साथ काम नहीं करता है ।
Jan

नहीं, लेकिन उस मामले में आप न्यूलाइन चरित्र का उपयोग कर सकते हैं यदि यह आपको परेशान नहीं करता है;)
मार्को

10

मुझे सोलारिस 10 के तहत अंतिम संशोधित फाइल खोजने में परेशानी हुई। इसके findपास कोई printfविकल्प नहीं है और statयह उपलब्ध नहीं है। मैंने निम्नलिखित समाधान की खोज की जो मेरे लिए अच्छा काम करता है:

find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1

फ़ाइल नाम दिखाने के लिए भी उपयोग करें

find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1

व्याख्या

  • find . -type f सभी फ़ाइलों को ढूँढता है और सूचीबद्ध करता है
  • sed 's/.*/"&"/' व्हॉट्सएप को हैंडल करने के लिए उद्धरणों में pathname लपेटता है
  • xargs ls -Eउद्धृत पथ को भेजता है ls, -Eविकल्प यह सुनिश्चित करता है कि एक पूर्ण टाइमस्टैम्प (प्रारूप -वर्ष-माह-दिन-घंटा-सेकंड-नैनो-सेकंड) ) लौटा दिया गया है
  • awk '{ print $6," ",$7 }' केवल तारीख और समय निकालता है
  • awk '{ print $6," ",$7," ",$9 }' अर्क तिथि, समय और फ़ाइल नाम
  • sort दिनांक के आधार पर छांटी गई फाइलों को लौटाता है
  • tail -1 केवल अंतिम संशोधित फ़ाइल लौटाता है

9

यह ठीक काम करने लगता है, यहां तक ​​कि उपनिर्देशिका के साथ भी:

find . -type f | xargs ls -ltr | tail -n 1

बहुत अधिक फ़ाइलों के मामले में, खोज को परिष्कृत करें।


1
अनावश्यक प्रतीत होने का -lविकल्प ls। बस -trपर्याप्त लगता है।
एक्यूमेनस

6
ऐसा लगता है कि यह प्रति निर्देशिका की तरह है, इसलिए यह जरूरी नहीं कि नवीनतम फ़ाइल
Fabian Schmengler

1
मामले में फ़ाइल पथ में स्थान बेहतर हैं:find . -type f -print0 | xargs -0 ls -ltr | tail -n 1
समय

यह मेरे लिए नवीनतम फ़ाइलों को नहीं ढूंढता है।
के-माइकल ऐ

1
यह सोचें कि यदि
फिल्नाम

7

मानव पठनीय टाइमस्टैम्प के साथ नवीनतम फ़ाइल दिखाता है:

find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1

परिणाम इस तरह दिखता है:

2015-10-06 11:30: +0200 ./foo/bar.txt

अधिक फ़ाइलों को दिखाने के लिए, -n1एक उच्च संख्या के साथ बदलें


5

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

find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'

1.7 मिलियन फ़ाइलों वाली एक निर्देशिका पर, मुझे 3.4s में सबसे हाल ही में एक मिलता है, जो 25.5s के मुकाबले 7.5x की गति-अप का उपयोग करता है।


बहुत अच्छा: मैंने अभी अंतिम प्रिंट का आदान-प्रदान किया है: सिस्टम ("ls -l $ f") यदि eof () को अच्छे तरीके से तारीख देखने के लिए भी।
मार्टिन टी।

@MartinT। : महान, और आपका स्वागत है। मेरे लिए यह अजीब है कि लोगों के पास इस तरह की चीजें हैं (O (n लॉग एन)) जब O (n) विधि उपलब्ध है। यह एकमात्र उत्तर है जो छँटाई से बचता है। BTW, मेरे द्वारा सुझाए गए कमांड का लक्ष्य केवल नवीनतम फ़ाइल का पथ खोजना है। आप अपने शेल में कमांड को उपनाम दे सकते हैं (जैसे कि lastfile) और फिर आप परिणाम के साथ जो चाहें कर सकते हैं, जैसे कि ls -l $(lastfile .), या open $(lastfile .)(मैक पर), आदि
पियरे डी

ओह, मैं सही हूं: मुझे नीचे एक और उत्तर (@marco) दिखाई देता है। +1।
पियरे डी

4

यह एक क्रमबद्ध सूची देता है:

find . -type f -ls 2>/dev/null | sort -M -k8,10 | head -n5

सॉर्ट कमांड में '-r' लगाकर ऑर्डर को उलट दें। यदि आप केवल फ़ाइल नाम चाहते हैं, तो "awk '{$ 11} प्रिंट करें" | इससे पहले ’| सिर'


3

उबंटू 13 पर, निम्नलिखित इसे करता है, हो सकता है कि यह तेजी से फैलता है, क्योंकि यह क्रम को उलट देता है और 'टेल' के बजाय 'हेड' का उपयोग करता है, जिससे काम कम हो जाता है। एक पेड़ में 11 सबसे नई फाइलें दिखाने के लिए:

खोजो। -Type f -printf '% T @% p \ n' | sort -n -r | सिर -11 | cut -f2- -d "" | sed -e 's, ^। / ,,' | xargs ls -U -l

यह फिर से छँटाई के बिना एक पूर्ण एलएस लिस्टिंग देता है और कष्टप्रद '' को छोड़ देता है '' / 'कि' खोज 'हर फ़ाइल नाम पर डालता है।

या, बैश फ़ंक्शन के रूप में:

treecent () {
  local numl
  if [[ 0 -eq $# ]] ; then
    numl=11   # Or whatever default you want.
  else
    numl=$1
  fi
  find . -type f -printf '%T@ %p\n' | sort -n -r | head -${numl} |  cut -f2- -d" " | sed -e 's,^\./,,' | xargs ls -U -l
}

फिर भी, अधिकांश कार्य प्लंड्रा के मूल समाधान द्वारा किए गए थे। धन्यवाद प्लांड्रा


3

मैंने उसी मुद्दे का सामना किया। मुझे सबसे हाल की फ़ाइल को पुनरावर्ती रूप से खोजने की आवश्यकता है। खोजने में लगभग 50 मिनट लगे।

यहाँ यह तेजी से करने के लिए एक छोटी सी स्क्रिप्ट है:

#!/bin/sh

CURRENT_DIR='.'

zob () {
    FILE=$(ls -Art1 ${CURRENT_DIR} | tail -n 1)
    if [ ! -f ${FILE} ]; then
        CURRENT_DIR="${CURRENT_DIR}/${FILE}"
        zob
    fi
    echo $FILE
    exit
}
zob

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


3

मुझे निम्नलिखित छोटे और अधिक व्याख्यात्मक आउटपुट के साथ मिलते हैं:

find . -type f -printf '%TF %TT %p\n' | sort | tail -1

मानकीकृत आईएसओ प्रारूप डेटाटाइम्स की निश्चित लंबाई को देखते हुए, लेक्सोग्राफिक सॉर्टिंग ठीक है और हमें -nइस प्रकार के विकल्प की आवश्यकता नहीं है ।

यदि आप टाइमस्टैम्प को फिर से हटाना चाहते हैं, तो आप उपयोग कर सकते हैं:

find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '

2

यदि statप्रत्येक फ़ाइल को व्यक्तिगत रूप से चलाना धीमा करना है तो आप xargsचीजों को थोड़ा गति देने के लिए उपयोग कर सकते हैं :

find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" " 

2

यह वर्तमान निर्देशिका में सभी निर्देशिकाओं के संशोधन समय को प्रत्येक निर्देशिका में नवीनतम फ़ाइल में बदलता है:

for dir in */; do find $dir -type f -printf '%T@ "%p"\n' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done

1
यह बुरी तरह से टूट जाता है अगर किसी भी डायर में रिक्त स्थान होते हैं - IFS को सेट करने और उद्धरण का उपयोग करने की आवश्यकता होती है: IFS = $ '\ n', $ dir के लिए (ढूँढें। / -Type d); गूंज "$ dir"; "$ dir" -type f -printf '% T @ "% p" \ n' खोजें | सॉर्ट-एन | पूंछ -1 | cut -f2- -d "" | xargs -I {} स्पर्श -r {} "$ dir"; किया हुआ;
एंडी ली रॉबिन्सन

2

यह सरल क्ली भी काम करेगा:

ls -1t | head -1

आप जिन फ़ाइलों को सूचीबद्ध करना चाहते हैं, उनकी संख्या -1 को बदल सकते हैं


10
नहीं, यह नहीं होगा, क्योंकि यह पुनरावर्ती नहीं है।
अरतज

1

मुझे कमांड ऊपर उपयोगी लगी, लेकिन मेरे मामले के लिए मुझे फ़ाइल की तारीख और समय देखने की आवश्यकता थी और साथ ही मुझे कई फाइलों के साथ एक समस्या थी जिनके नाम में स्थान हैं। यहाँ मेरा काम कर समाधान है।

find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " | sed 's/.*/"&"/' | xargs ls -l

1

निम्नलिखित आदेश सोलारिस पर काम किया:

find . -name "*zip" -type f | xargs ls -ltr | tail -1 

1

छिपी हुई फ़ाइलों को अनदेखा करना - अच्छा और तेज़ समय टिकट के साथ

$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10

परिणाम

फ़ाइल नाम में रिक्त स्थान को अच्छी तरह से संभालता है - ऐसा नहीं है कि इन का उपयोग किया जाना चाहिए!

2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht
2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht
2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht
2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht

अधिक

findलिंक के बाद और अधिक शानदार।


1

/ Target_directory और इसके सभी उप-निर्देशिकाओं में फ़ाइलों की खोज करने के लिए, जिन्हें पिछले 60 मिनट में संशोधित किया गया है:

$ find /target_directory -type f -mmin -60

सबसे हाल ही में संशोधित फ़ाइलों को खोजने के लिए, अद्यतन समय के रिवर्स क्रम में क्रमबद्ध (यानी, सबसे हाल ही में अद्यतन की गई फ़ाइलें):

$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r

0

मुझे यह पसंद है, यह छोटा है:

find . -type f -print0|xargs -0 ls -drt|tail -n 1

0

मैंने इस प्रश्न के लिए एक pypi / github पैकेज लिखा क्योंकि मुझे इसके समाधान की आवश्यकता थी।

https://github.com/bucknerns/logtail

इंस्टॉल:

pip install logtail

उपयोग: पूंछ बदल फ़ाइलें

logtail <log dir> [<glob match: default=*.log>]

उपयोग 2: संपादक में नवीनतम परिवर्तित फ़ाइल खोलता है

editlatest <log dir> [<glob match: default=*.log>]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.