वर्ष के आधार पर फ़ाइलों को कैसे स्थानांतरित किया जाए


15

मुझे एक वर्ष के आधार पर फाइलों को स्थानांतरित करने की आवश्यकता है। मैंने findकमांड का इस्तेमाल किया

find /media/WD/backup/osool/olddata/ -mtime +470 -exec ls -lrth {} \;|sort -k6

लेकिन इस आदेश को सफलतापूर्वक निष्पादित करने के लिए मुझे यह जानने की आवश्यकता है कि mtimeअब 470 केवल एक अनुमान है। मतलब अगर मैं वर्ष 2012 दे सकता हूं तो यह मुझे केवल 2012 से संबंधित फाइलें देता है।

तो मुझे सलाह है कि कैसे करना है

वर्ष 2012 के आधार पर फाइलें खोजें और उन्हें अन्य निर्देशिका में स्थानांतरित करें।

OS release 5.2

FIND version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX 

क्या इसके -exec ls ... \;बजाय उपयोग करने के लिए समझ में आता है -exec ... +? क्या आपका पता उसके लिए बहुत पुराना है? उस मामले में find ... -print0 | xargs -0 ls...बहुत तेज होगा।
हॉके लैगिंग

मैं इन सवालों (और उत्तरों) की कामना करता हूं जो कोरुटिल्स के साथ सौदा करते हैं, यह निर्दिष्ट करेंगे कि क्या हम GNU या BSD (या अन्य) बर्तनों के साथ काम कर रहे हैं।
भूलभुलैया

जवाबों:


39

आप इसके लिए -newermtविकल्प का उपयोग करना चाहते हैं find:

find /media/WD/backup/osool/olddata/ -newermt 20120101 -not -newermt 20130101

2012 में संशोधन समय के साथ सभी फाइलें प्राप्त करने के लिए।

यदि आपका खोज समर्थन नहीं करता है -newermtतो आप ऑफ़सेट गणना का उपयोग करने से रोकने के लिए निम्न कार्य भी कर सकते हैं:

touch -d 20120101 /var/tmp/2012.ref
touch -d 20130101 /var/tmp/2013.ref
find /media/WD/backup/osool/olddata/ -newer /var/tmp/2012.ref -not -newer /var/tmp/2013.ref

1
-newermt झंडा फ़ाइनल कमांड में उपलब्ध नहीं है
OmiPenguin

यह एक पुराना संस्करण होना चाहिए जो आपके आरएचईएल के साथ आता है? मैं उस उत्तर के लिए एक विकल्प प्रदान करूंगा
एंथन

हां यह एक 5.2 है
ओमीपेंगिन

मुझे लगता है कि यह आरएचईएल का संशोधन है, न कि find(मुझे संस्करण 4.4.2 मिला है)
एंथन

1
V4.3.3, gnu.org/software/findutils/manual/html_mono/find.html के बाद के संस्करणों तक न्यूटर्म स्विच नहीं दिखा ।
स्लम

5
touch --date=2011-12-31T23:59:59 start
touch --date=2012-12-31T23:59:59 stop
find / -newer start \! -newer stop -printf %Tx" "%p\\n

-exec ls कोई मतलब नहीं है।


1
-exec ls -lपरीक्षण करते समय और भी अधिक समझ में आता है।
बजे एक CVn

@ माइकलकॉर्जलिंग findसब कुछ प्रिंट कर सकता है जो lsकर सकता है। ठीक है, एक अपवाद के साथ: अप्रिय वर्णों से बचना / उद्धृत करना। लेकिन सामान्य तौर पर इसका उत्पादन findसीधे हल किया जा सकता है। एल एस के बेकार कॉल पूरी बात तेजी से नहीं बनाते हैं।
हौके लैजिंग

मैं अक्सर परीक्षण के दौरान कुछ समान (हालांकि व्यक्तिगत रूप से पसंद -printया संभवतः -ls ) कुछ का उपयोग करता हूं । उपयोग करने -exec ls {}का लाभ यह है कि यह पहले से ही खोजने के लिए कुछ बाहरी निष्पादित करता है । इसलिए जब तक आप स्विच lsकरते हैं mv, तब तक वास्तविक परिवर्तन न्यूनतम होते हैं।
बजे एक CVn

3

मैन पेज के अनुसार, इस तर्क के लिए-दिनों की संख्या है जिसे आप खोज रहे हैं। आप date +%jवर्तमान वर्ष की पहली जनवरी से दिनों की संख्या का पता लगाने के लिए उपयोग कर सकते हैं ।


2
बढ़िया तरीका। बहुत "नाइटपिकी" होना: -मटाइम -1: पिछले 24 घंटों में कोई फ़ाइल है। सिर्फ कल (या आज) से फाइलें नहीं। तो, थोड़ा "ओवरलैप" भी होगा: यदि आप यह निर्धारित करते हैं कि 2012 से 120 दिन हो गए हैं, और आज यह 15:45 है जब आप स्क्रिप्ट लॉन्च करते हैं, तो आप 31 15:45 तक फ़ाइलों को चुनने का अंत करेंगे ( और उस दिन के अंतिम वाले नहीं) ... आप शायद उपयोग कर सकते हैं: nb_day - 1, और फिर 2013 से तारीख करने वाले कुछ लोगों को "मातम" (वे एक ls द्वारा पाया जा सकता है -l | grep -v, BUT उत्पादन अलग है अगर वे केवल 1 दिन पुराने हैं ... बहुत नुकसान ...)
ओलिवियर दुलैक

आप -daystartविकल्प का उपयोग करना चाहते हैं यदि आप साथ काम करने जा रहे हैं -mtime। अन्यथा आपको वर्ष की शुरुआत और अंत के आसपास की फ़ाइलों के साथ समस्याएँ होंगी जो भी आप तब तक चालू करेंगे जब तक कि आप आधी रात को इसे ठीक से नहीं चलाते। यदि आप नए साल के बाद से आसानी से मिनटों की संख्या पा सकते हैं तो आप इसकी -mminतुलना में अधिक सटीकता के साथ -mtimeकर सकते हैं। लेकिन -mtimeकम फ़ाइलों के लिए (आधी रात के आसपास एक मिनट के रूप में) उन लोगों के साथ भी यही समस्या है ।
एंथन

1
हाँ, मैन पेज मैं फिर से पढ़ रहा हूँ, यह देख रहा हूँ कि यह कैसे घंटों तक टूट जाता है इसलिए एक साधारण कार्य करना find -mtime $("date -+%j")शायद ओपी को नहीं देगा कि वे किस लिए जा रहे हैं। मैं इसे पश्चाताप के लिए छोड़ रहा हूं, हालांकि ऐसा लगता है कि लोगों में गिरने के लिए एक संभव अंधाधुंध की तरह है।
ब्राचली

2

आप निम्नलिखित वन-लाइनर्स के रूप में statऔर / या dateकमांड के साथ संयोजन का उपयोग करने का प्रयास कर सकते हैं :

बीएसडी / मैक ओएस एक्स:

find . -type f -print | while read file; do eval `stat -s "$file"`; year=`date -jf "%s" "+%Y" "$st_mtime"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

लिनक्स:

find . -type f -print | while read file; do year=`date -r "$file" "+%Y"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

दोनों मामलों में दृष्टिकोण का उपयोग dateहर फाइल के अंतिम संशोधन समय से वर्ष निकालने के लिए कमांड का उपयोग करना और फिर इस वर्ष के साथ एक पथ का निर्माण करना है। mkdir -pयदि यह पहले से मौजूद नहीं है, तो कमांड इस रास्ते को बनाएगी। बेशक आप findअपनी खोज को परिष्कृत करने के लिए कुछ अन्य विकल्पों का उपयोग कर सकते हैं ।


1

यदि आप कार्यशील निर्देशिका से ऐसा करते हैं, तो आप इसके बजाय यह कर सकते हैं:

ls -l |awk '{ if ($8 == "2013") print $9 }'

यह चीजों को काफी सरल करता है और किसी भी ओवरलैप का कारण नहीं बनता है। लेकिन यह भी माना जाता है कि ये फाइलें 6 महीने से अधिक पुरानी हैं, और यह lsसटीक समय के बजाय वर्ष को प्रिंट करेगी।

6 महीने से अधिक पुरानी नई फ़ाइलों के लिए, आपको इसे इसके साथ बदलना होगा:

ls -l |awk '{ if ($6 == "May") print $9 }' 

या कुछ इसी तरह, महीने पर निर्भर करता है। यदि आप फ़ाइलों को स्थानांतरित करने के लिए महीनों की एक सूची बनाना चाहते हैं (या यदि आप वर्षों के लिए एक सूची बनाना चाहते हैं) तो ऐसा करें:

month="May Jun Jul"; 
for i in `echo $month`; 
do 
    for j in `ls -l |awk '{ if ($6 == "'$i'") print $9}'`
    do
        mkdir -p $i
        mv $j $i
    done
done
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.