আমি লগ ফাইলগুলিতে পূর্ণ একটি ডিরেক্টরি পরিচালনা করার চেষ্টা করছি। রাতে, আমি সাম্প্রতিক 10 টি ছাড়া সমস্ত মুছতে চাই। আমি একক আদেশে এটি কীভাবে করতে পারি?
আমি লগ ফাইলগুলিতে পূর্ণ একটি ডিরেক্টরি পরিচালনা করার চেষ্টা করছি। রাতে, আমি সাম্প্রতিক 10 টি ছাড়া সমস্ত মুছতে চাই। আমি একক আদেশে এটি কীভাবে করতে পারি?
উত্তর:
একটি বহনযোগ্য এবং নির্ভরযোগ্য সমাধানের জন্য, এটি চেষ্টা করুন:
ls -1tr | head -n -10 | xargs -d '\n' rm -f --
tail -n -10
অন্যান্য উত্তর এক সিনট্যাক্স (অর্থাত, আমার RHEL5 সিস্টেমে নয়) সব জায়গায় কাজ বলে মনে হচ্ছে না।
এবং কমান্ড লাইন ব্যবহার করে $()
বা চালানো ঝুঁকিপূর্ণ``
rm
xargs
এই উভয় সমস্যার সমাধান করে কারণ এটি অক্ষরের সীমাতে কয়টি আর্গ পাস করতে পারে তা স্বয়ংক্রিয়ভাবেই বের হয়ে যাবে এবং -d '\n'
এটি কেবল ইনপুটটির লাইন সীমানায় বিভক্ত হবে। প্রযুক্তিগতভাবে এটি ফাইললাইমগুলির মধ্যে একটি নতুন লাইনের সাথে এখনও সমস্যা তৈরি করতে পারে তবে স্পেস সহ ফাইলনামগুলির তুলনায় এটি খুব কম সাধারণ এবং নতুন লাইনের আশেপাশের একমাত্র উপায়টি পার্ল না হলে সম্ভবত কমপক্ষে বিশৃঙ্খলা জড়িত, আরও অনেক জটিল হবে।
আপনার যদি xargs না থাকে (পুরানো এআইএক্স সিস্টেম, সম্ভবত?) আপনি এটিকে একটি লুপ তৈরি করতে পারেন:
ls -1tr | head -n -10 | while IFS= read -r f; do
rm -f "$f"
done
এটি কিছুটা ধীর হবে কারণ এটি rm
প্রতিটি ফাইলের জন্য পৃথক করে, তবে উপরের 1 এবং 2 কেভ্যাটস এড়িয়ে চলবে (তবে ফাইলের নামে নতুন লাইনে ভুগছে)।
head(1)
ম্যান পেজ থেকে:-n, --lines=[-]K print the first K lines instead of the first 10; with the leading '-', print all but the last K lines of each file
head
এবং xargs
ত্রুটি দিন। সঠিক বিকল্পগুলি head -n 10
এবং xargs rm -f
। পূর্ণ কমান্ডটি হ'লls -1tr ./ | head -n 10 | xargs rm -rf
ls -1tr
হ'ল এক নম্বর হ'ল "এল" বর্ণটি নয়।
আপনার স্ক্রিপ্টে আপনি যে কোডটি অন্তর্ভুক্ত করতে চান তা হ'ল
rm -f $(ls -1t /path/to/your/logs/ | tail -n +11)
-1
(সাংখ্যিক একটি) বিকল্প কপি করে প্রিন্ট একটি একক লাইন প্রতিটি ফাইল, নিরাপদ হতে। -f
বিকল্প rm
যখন এটি জন্য অবর্তমান ফাইল উপেক্ষা করা বলে ls
আয় নেই।
/path/to/your/logs
আপনার সঠিক পথে প্রবেশের জন্য তৈরি করা হয়েছে made বাগটি খুঁজে পেতে পার্টসটি একা চালাবেন ls -t /path/...
এবং ls -t /path/... | tail -n +11
একা এবং ফলাফলটি সঠিক কিনা তা যাচাই করুন।
+
নম্বর আগে মনে মনে । এটি tail
সর্বশেষ এন উপাদানগুলি মুদ্রণ করে না তবে সমস্ত উপাদান এন'থ থেকে শুরু করে। আমি আবার চেক ইন করেছি এবং কমান্ডটি অবশ্যই সমস্ত পরিস্থিতিতে কেবলমাত্র 10 টিরও বেশি পুরানো উপাদানগুলি সরিয়ে ফেলবে।
ls
কোনও ফাইলের নাম rm -f
স্পষ্টতই পার্সিং ls
করা মন্দ ।
যদি প্রতিটি ফাইল প্রতিদিন তৈরি হয় এবং আপনি ফাইলগুলি গত 10 দিনের মধ্যে রাখতে চান তবে আপনি এটি করতে পারেন:
find /path/to/files -mtime 10 -delete
অথবা যদি প্রতিটি ফাইল নির্বিচারে তৈরি করা হয়:
find /path/to/files -maxdepth 1 -type f -printf '%Ts\t%P\n' | sort -n | head -n -10 | cut -f 2- | xargs rm -rf
-mtime 10 -delete
ঠিক 10 দিন আগে পরিবর্তিত ফাইলগুলি মুছুন। পুরানো ফাইল মুছে ফেলা হবে না। -mtime +11 -delete
শেষ 10 দিনের লগ ফাইল রেখে 11 বা আরও দিন আগে সংশোধিত ফাইলগুলি মুছবে।
%p
পরিবর্তে এর ব্যবহারের %P
প্রয়োজন printf
যাতে ফাইলগুলি পুরো পথ পায়। অন্যথায় rm -rf
কাজ করে না।
আমি আইজাকের পদ্ধতিকে কিছুটা পরিবর্তন করেছি।
এটি এখন একটি কাঙ্ক্ষিত পথ নিয়ে কাজ করে:
ls -d -1tr /path/to/folder/* | head -n -10 | xargs -d '\n' rm -f
থেকে এখানে :
#! /bin/sh
# keepnewest
#
# Simple directory trimming tool to handle housekeeping
# Scans a directory and deletes all but the N newest files
#
# Usage: cleanup <dir> <number of files to keep>
#
# v 1.0 Piers Goodhew 1/mar/2007. No rights retained.
if [ $# -ne 2 ]; then
echo 1>&2 "Usage: $0 <dir> <number of files to keep>"
exit 1
fi
cd $1
files_in_dir=`ls | wc -l`
files_to_delete=`expr $files_in_dir - $2`
if [ $files_to_delete -gt 0 ]; then
ls -t | tail -n $files_to_delete | xargs rm
if [ $? -ne 0 ]; then
echo "An error ocurred deleting the files"
exit 1
else
echo "$files_to_delete file(s) deleted."
fi
else
echo "nothing to delete!"
fi
বাশে আপনি চেষ্টা করতে পারেন:
ls -1t | (i=0; while read f; do
if [ $i -lt 10 ]; then
((i++))
continue
else
rm -f "$f"
fi
done)
এটি 10 টি নতুন আলগুলি বাকিগুলি মুছে ফেলে। লোগ্রোটেট আরও ভাল হতে পারে, আমি কেবল ভুল শেল সম্পর্কিত উত্তরগুলি সংশোধন করতে চাই।
নিশ্চিত নয় যে এটি কাউকে সাহায্য করবে তবে উইঙ্কি চরিত্রগুলির সাথে সম্ভাব্য সমস্যাগুলি এড়াতে আমি সারণিটি ব্যবহার ls
করতে পেরেছি inode
তবে মুছে ফেলার জন্য ফাইলগুলি ব্যবহার করি।
বর্তমান ডিরেক্টরিগুলির জন্য, এটি সংশোধন সময়ের উপর ভিত্তি করে সবচেয়ে সাম্প্রতিক 10 টি ফাইল রাখে।
ls -1tri | awk '{print $1}' | head -n -10 | xargs -n1 -t -Iinode find . -inum inode -exec rm -i {} \;
আমার ব্যস্তবক্স (রাউটার) এর জন্য একটি মার্জিত সমাধান দরকার ছিল, সমস্ত xargs বা অ্যারের সমাধানগুলি আমার পক্ষে অকেজো - সেখানে এই জাতীয় কোনও আদেশ উপলব্ধ নেই। আমরা 10 টি আইটেমের কথা বলছি এবং অগত্যা 10 দিন নয়, কারণ অনুসন্ধান এবং এমটাইম সঠিক উত্তর নয়। এস্পোর উত্তরটি সবচেয়ে সংক্ষিপ্ত এবং পরিষ্কার এবং সম্ভবত সবচেয়ে বিপরীত ছিল।
স্পেসগুলির সাথে ত্রুটি এবং যখন কোনও ফাইল মুছতে হয় না তখন উভয়ই স্ট্যান্ডার্ড পদ্ধতিতে সমাধান করা হয়:
rm "$(ls -td *.tar | awk 'NR>7')" 2>&-
আরও শিক্ষামূলক সংস্করণে বিট করুন: আমরা যদি অন্যভাবে জঞ্জাল ব্যবহার করি তবে আমরা এটি সব করতে পারি। সাধারণত, আমি এই পদ্ধতিটি ব্যবহার করে ভেরিয়েবলগুলি sh থেকে sh এ ফিরে যেতে (রিটার্ন) করতে পারি। যেহেতু আমরা পুরোটা সময় পড়তে পারি না যা করতে পারি না, আমি আলাদা হতে অনুরোধ করি: এখানে পদ্ধতিটি।
ফাইলের নাম শূন্যস্থান সম্পর্কিত কোনও সমস্যা ছাড়াই .tar ফাইলগুলির উদাহরণ। পরীক্ষা করতে, "আরএম" "ls" এর সাথে প্রতিস্থাপন করুন।
eval $(ls -td *.tar | awk 'NR>7 { print "rm \"" $0 "\""}')
ব্যাখ্যা:
ls -td *.tar
সময় অনুসারে বাছাই করা সমস্ত .tar ফাইলগুলি তালিকাবদ্ধ করে। বর্তমান ফোল্ডারে থাকা সমস্ত ফাইলগুলিতে প্রয়োগ করতে, "ডি * .আর" অংশটি সরান
awk 'NR>7...
প্রথম 7 লাইন এড়িয়ে যায়
print "rm \"" $0 "\""
একটি লাইন তৈরি করে: আরএম "ফাইলের নাম"
eval
এটি কার্যকর করে
যেহেতু আমরা ব্যবহার করছি rm
, আমি উপরের কমান্ডটি কোনও স্ক্রিপ্টে ব্যবহার করব না! উইজার ব্যবহারটি হ'ল:
(cd /FolderToDeleteWithin && eval $(ls -td *.tar | awk 'NR>7 { print "rm \"" $0 "\""}'))
ls -t
কমান্ড ব্যবহারের ক্ষেত্রে যেমন নিরীহ উদাহরণগুলিতে কোনও ক্ষতি করে না: touch 'foo " bar'
এবং touch 'hello * world'
। বাস্তব জীবনে আমরা কখনও এই জাতীয় নাম দিয়ে ফাইল তৈরি করি না!
সাইড নোট. আমরা যদি এইভাবে sh এর কাছে একটি ভেরিয়েবল পাস করতে চাইতাম, তবে আমরা কেবল মুদ্রণটি পরিবর্তন করব:
print "VarName="$1
পরিবর্তনশীল সেট করতে VarName
মূল্য $1
। একযোগে একাধিক ভেরিয়েবল তৈরি করা যেতে পারে। এটি VarName
একটি সাধারণ sh পরিবর্তনশীল হয়ে যায় এবং পরে কোনও স্ক্রিপ্ট বা শেল এ সাধারণত ব্যবহার করা যেতে পারে। সুতরাং, awk সহ ভেরিয়েবলগুলি তৈরি করতে এবং সেগুলি শেলের কাছে ফিরিয়ে দিতে:
eval $(ls -td *.tar | awk 'NR>7 { print "VarName="$1 }'); echo "$VarName"
আইজ্যাক ফ্রিম্যানের প্রতিক্রিয়ার ভিত্তিতে, তবে যে কোনও ডিরেক্টরিতে কাজ করছেন:
ls -1tr $PATH_TO_DELETE/* | head -n -10 | xargs -d '\n' rm -f --
আপনি যেমন উপসর্গ সেট করতে পারেন $PATH_TO_DELETE/testFi*
আপনি যদি উইলের *
পরে PATH
ls
নিখুঁত ফাইলের নামগুলি আউটপুট ব্যবহার করেন তবে কমপক্ষে "আমার" বাশে :)