जवाबों:
यदि आप फ़ाइलों पर लूप करना चाहते हैं, तो कभी भी उपयोग न करेंls
*। tl; dr ऐसी बहुत सी स्थितियाँ हैं जहाँ आप गलत फ़ाइल या सभी फ़ाइलों को हटाना समाप्त कर देंगे।
उस ने कहा, दुर्भाग्य से यह बैश में सही करने के लिए एक मुश्किल काम है। वहाँ कम से ऊपर एक काम कर जवाब एक डुप्लिकेट सवाल मेरे यहां तक कि पुरानेfind_date_sorted
जो आप छोटे संशोधनों के साथ उपयोग कर सकते हैं:
counter=0
while IFS= read -r -d '' -u 9
do
let ++counter
if [[ counter -gt 3 ]]
then
path="${REPLY#* }" # Remove the modification time
echo -e "$path" # Test
# rm -v -- "$path" # Uncomment when you're sure it works
fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\0' | sort -rz) # Find and sort by date, newest first
* कोई अपराध नहीं - मैं भी ls
पहले इस्तेमाल किया । लेकिन यह वास्तव में सुरक्षित नहीं है।
संपादित करें: इकाई परीक्षणों के साथ नयाfind_date_sorted
।
((++counter>3))
अपने परीक्षण के रूप में प्रयास करें। यह अच्छी तरह से रसीला है। ऑनलाइनर के रूप में: यदि संक्षिप्तता एक फ़ंक्शन में कोड को लपेटने की चिंता है, तो इसके बारे में चिंता न करें।
सभी को हटाने के लिए, लेकिन एक zsh ग्लोब का उपयोग करके 3 सबसे नई फाइलें, आप Om
(कैपिटल ओ) का उपयोग करके फाइलों को सबसे पुरानी से लेकर नई तक छांट सकते हैं और अपनी पसंद की फाइलों को हथियाने के लिए एक सबस्क्रिप्ट कर सकते हैं।
rm ./*(Om[1,-4])
# | |||| ` stop at the 4th to the last file (leaving out the 3 newest)
# | |||` start with first file (oldest in this case)
# | ||` subscript to pick one or a range of files
# | |` look at modified time
# | ` sort in descending order
# ` start by looking at all files
अन्य उदाहरण:
# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])
# delete oldest two files
rm ./*(Om[1,2])
# delete everything but the oldest file
rm ./*(om[1,-2])
अब तक सबसे आसान तरीका है zsh और इसके ग्लोब क्वालीफायर का उपयोग करना : Om
कम उम्र (जैसे सबसे पुराना) [1,3]
को छाँटना और केवल पहले तीन मैचों को बरकरार रखना।
rm ./*(Om[1,3])
यह भी देखें कि मैं अधिक उदाहरणों के लिए zsh में ग्लोब कैसे फ़िल्टर कर सकता हूं ।
और l0b0 की सलाह पर ध्यान दें : यदि आपके पास फ़ाइल नाम हैं जिनमें शेल विशेष वर्ण हैं तो आपका कोड बुरी तरह से टूट जाएगा।
निर्देशिका में नवीनतम फ़ाइल प्राप्त करने के लिए आप निम्न फ़ंक्शन का उपयोग कर सकते हैं:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
प्रत्येक पुनरावृत्ति के बाद सबसे नई फ़ाइल को एक्सेल करके फाइलों का एक अलग सेट दें।
युक्ति: यदि आप "$ {फ़ाइलें [@]}" नामक एक सरणी में फ़ाइलों का प्रारंभिक सेट रखते हैं, तो मिली नई फ़ाइल के सूचकांक और unset 'files[index]'
अगले पुनरावृत्ति से पहले सहेजें ।
उपयोग: newest_in [set of files/directories]
नमूना उत्पादन:
[rany$] newest_in ./*
foo.txt
[rany$]
सबसे पहले, -R
विकल्प पुनरावृत्ति के लिए है, जो कि शायद आप क्या चाहते हैं - जो सभी उपनिर्देशिकाओं में भी खोज करेगा। दूसरा, <
ऑपरेटर (जब पुनर्निर्देशन के रूप में नहीं देखा जा रहा है) स्ट्रिंग तुलना के लिए है। आप शायद चाहते हैं -lt
। प्रयत्न:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
लेकिन मैं यहां खोजने का उपयोग करूंगा:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
मुझे पता है कि यह पाप करना पाप है ls
, लेकिन इस बारे में क्या:
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
5 खाली फ़ाइलों के साथ एक त्वरित परीक्षण:
$ >1
$ >2
$ >3
$ >4
$ >5
$ find . -type f -maxdepth 1 | xargs ls -lt | sed '1,3d' | awk '{print $9}' | xargs rm
$ ls -1
3
4
5
ls
आउटपुट और उपयोग करना find
और xargs
एक साथ गलत तरीके से। यदि आप संयोजन करते हैं find
और xargs
मैं आपको find
s -print0
और तदनुसार xargs
s -O
विकल्पों का उपयोग करने की सलाह देता हूं । विषय के बारे में अधिक जानकारी के लिए खोज का उपयोग करने के बारे में पढ़ें । आप यह भी देख सकते हैं कि क्यों पार्सिंग एलएस बहुत खराब है।
यह एक-लाइनर यह सब मुझे लगता है:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
यहाँ एक समाधान है:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)