আমি কীভাবে লিনাক্সের 10 টি নতুন ফাইল বাদে সবগুলি মুছব?


49

আমি লগ ফাইলগুলিতে পূর্ণ একটি ডিরেক্টরি পরিচালনা করার চেষ্টা করছি। রাতে, আমি সাম্প্রতিক 10 টি ছাড়া সমস্ত মুছতে চাই। আমি একক আদেশে এটি কীভাবে করতে পারি?


3
লোগ্রোটেটটি দেখুন
নিটল


@ মাইক্রেল আমার আলোচনাটি যদি তৈরি হয় তবে আমার কীভাবে এটির একটি সদৃশ হতে পারে?
dev4Live

@ আপনারা "আপনার"? আমি উভয় প্রশ্নে আপনার নাম দেখতে পাচ্ছি না, তাই আপনি কী বোঝাতে চাইছেন তা আমি নিশ্চিত নই। আমার মন্তব্য এমনকি অন্যটির নকল যা ইঙ্গিত দেয় না। তবে এটি কোনও বিষয় নয় - এটি একটি লিঙ্ক সহ কেবল একটি মন্তব্য। এটি যে কোনও প্রশ্নে বা উভয় প্রশ্নের সাথে যুক্ত হতে পারে। এটি অন্য কারও - অ্যাডমিনের - একজন বা অন্যটিকে নকল হিসাবে চিহ্নিত করা। কোনও নিন্দিত হত্যার উদ্দেশ্য ছিল না বা কোনওটিকেই অনুধাবন করা উচিত নয়। কোন প্রশ্নটি প্রথমে ছিল তার চেয়েও গুরুত্বপূর্ণ, কোন প্রশ্নের সর্বোত্তম উত্তর রয়েছে - আবার, লিঙ্কটি এই আলোচনাকে সহজতর করে, এটি উত্তর নির্ধারণ করে না।
মাইকেল 25

@ মাইকেল এটা সত্যিই বিজোড়। এই থ্রেডটি আমার দ্বারা খোলা হয়েছিল তবে এটি সম্ভবত আমার ব্যবহারকারীর নাম নয়। তবে আমি এই থ্রেড সম্পর্কে অবহিত করছি।
dev4Live

উত্তর:


58

একটি বহনযোগ্য এবং নির্ভরযোগ্য সমাধানের জন্য, এটি চেষ্টা করুন:

ls -1tr | head -n -10 | xargs -d '\n' rm -f --

tail -n -10অন্যান্য উত্তর এক সিনট্যাক্স (অর্থাত, আমার RHEL5 সিস্টেমে নয়) সব জায়গায় কাজ বলে মনে হচ্ছে না।

এবং কমান্ড লাইন ব্যবহার করে $()বা চালানো ঝুঁকিপূর্ণ``rm

  1. সাদা জায়গার সাথে ফাইলের নামগুলি বিভক্ত করা
  2. সর্বাধিক কমান্ডলাইন অক্ষরের সীমা ছাড়িয়ে গেছে।

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
আইজাক ফ্রিম্যান

সোলারিস 10 এ headএবং xargsত্রুটি দিন। সঠিক বিকল্পগুলি head -n 10এবং xargs rm -f। পূর্ণ কমান্ডটি হ'লls -1tr ./ | head -n 10 | xargs rm -rf
দিমিত্রিসান্ডালভ

1
নোটটি ls -1trহ'ল এক নম্বর হ'ল "এল" বর্ণটি নয়।
চমত্কার লিনাক্স ব্যবহারকারী

1
এটিও লক্ষ করা উচিত যে নতুন ফাইলগুলি এক্স ফাইল ফাইলের ক্ষেত্রে বিরল তবে বৈধ অক্ষর। এর অর্থ হ'ল যদি আপনার "সেই", এবং "সেই কিছু" ফাইল থাকে তবে যদি এই স্ক্রিপ্টটি "সেই" কিছু "হিট করে তবে এটি" সেই "মুছে ফেলবে," জিনিস "মুছতে না পারলে ত্রুটি করে এবং ছেড়ে যায় "যে thing n কিছুই" (উদ্দেশ্য লক্ষ্য) ক্ষতিগ্রস্ত।
সিনটহেড

1
@ আইসাকফ্রিমন আমি আমার খারাপ পরামর্শগুলি মুছে ফেলেছি, চিয়ার্স।
ওয়াল্ফ

20

আপনার স্ক্রিপ্টে আপনি যে কোডটি অন্তর্ভুক্ত করতে চান তা হ'ল

 rm -f $(ls -1t /path/to/your/logs/ | tail -n +11)

-1(সাংখ্যিক একটি) বিকল্প কপি করে প্রিন্ট একটি একক লাইন প্রতিটি ফাইল, নিরাপদ হতে। -fবিকল্প rmযখন এটি জন্য অবর্তমান ফাইল উপেক্ষা করা বলে lsআয় নেই।


আসল পোস্টার, এখানে। আমি এই কমান্ডটি চেষ্টা করেছিলাম, তবে এটি কার্যকর হয় না - আমি ত্রুটিটি পেয়েছি "আরএম: অনুপস্থিত অপারেন্ড"
ব্যবহারকারী 75814

2
আপনি কি সঠিক পথটি ব্যবহার করেছেন? অবশ্যই /path/to/your/logsআপনার সঠিক পথে প্রবেশের জন্য তৈরি করা হয়েছে made বাগটি খুঁজে পেতে পার্টসটি একা চালাবেন ls -t /path/...এবং ls -t /path/... | tail -n +11একা এবং ফলাফলটি সঠিক কিনা তা যাচাই করুন।
ড্যানিয়েল বোহ্মার

1
@ হক্কলিজিং আমি নিশ্চিত যে আপনার কিছু ভুল হয়েছে। +নম্বর আগে মনে মনে । এটি tailসর্বশেষ এন উপাদানগুলি মুদ্রণ করে না তবে সমস্ত উপাদান এন'থ থেকে শুরু করে। আমি আবার চেক ইন করেছি এবং কমান্ডটি অবশ্যই সমস্ত পরিস্থিতিতে কেবলমাত্র 10 টিরও বেশি পুরানো উপাদানগুলি সরিয়ে ফেলবে।
ড্যানিয়েল বুহমার

@ হ্যাलो, দুঃখিত।
হউক লেগেইং

2
আমি মনে করি আপনার উত্তরটি খুব বিপজ্জনক lsকোনও ফাইলের নাম rm -f
ছাপায়

14

স্পষ্টতই পার্সিং 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

5
-mtime 10 -deleteঠিক 10 দিন আগে পরিবর্তিত ফাইলগুলি মুছুন। পুরানো ফাইল মুছে ফেলা হবে না। -mtime +11 -deleteশেষ 10 দিনের লগ ফাইল রেখে 11 বা আরও দিন আগে সংশোধিত ফাইলগুলি মুছবে।
মার্কাস

1
আমি মনে করি %pপরিবর্তে এর ব্যবহারের %Pপ্রয়োজন printfযাতে ফাইলগুলি পুরো পথ পায়। অন্যথায় rm -rfকাজ করে না।
জলপবা

9

লোগ্রোটেটের মতো একটি সরঞ্জাম এটি আপনার জন্য করে। এটি লগ পরিচালনা অনেক সহজ করে তোলে। আপনি অতিরিক্ত ক্লিনআপ রুটিনগুলিকেও অন্তর্ভুক্ত করতে পারেন হ্যালো সাজেস্টেড হিসাবে।



1

থেকে এখানে :

#! /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

1
এই উত্তর সরবরাহ করার জন্য ধন্যবাদ। এই জাতীয় কোড সরবরাহ করা সহায়ক, এটি কীভাবে এটি ব্যবহার হতে পারে বা কোড কী করে সে সম্পর্কে কিছু অতিরিক্ত তথ্য সরবরাহ করতে সহায়তা করে। আপনার পোস্টে ভবিষ্যতের উন্নতি করতে আপনি সম্পাদনা বোতামটি ব্যবহার করতে পারেন ।
নিখোঁজ

1

বাশে আপনি চেষ্টা করতে পারেন:

ls -1t | (i=0; while read f; do
  if [ $i -lt 10 ]; then
    ((i++))
    continue
  else
    rm -f "$f"
  fi
done)

এটি 10 ​​টি নতুন আলগুলি বাকিগুলি মুছে ফেলে। লোগ্রোটেট আরও ভাল হতে পারে, আমি কেবল ভুল শেল সম্পর্কিত উত্তরগুলি সংশোধন করতে চাই।


1

নিশ্চিত নয় যে এটি কাউকে সাহায্য করবে তবে উইঙ্কি চরিত্রগুলির সাথে সম্ভাব্য সমস্যাগুলি এড়াতে আমি সারণিটি ব্যবহার lsকরতে পেরেছি inodeতবে মুছে ফেলার জন্য ফাইলগুলি ব্যবহার করি।

বর্তমান ডিরেক্টরিগুলির জন্য, এটি সংশোধন সময়ের উপর ভিত্তি করে সবচেয়ে সাম্প্রতিক 10 টি ফাইল রাখে।

ls -1tri | awk '{print $1}' | head -n -10 | xargs -n1 -t -Iinode find . -inum inode -exec rm -i {} \;


0

আমার ব্যস্তবক্স (রাউটার) এর জন্য একটি মার্জিত সমাধান দরকার ছিল, সমস্ত 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"

0

আমি একমত যে ls কে পার্সিং করা খারাপ!

নিশ্চিত করুন যে কেবল সর্বশেষ 5 টি ফাইলের /srv/backupsপথে রয়েছে।

find /srv/backups -maxdepth 1 -type f -printf '%Ts\t%P\n' \
    | sort -rn \
    | tail -n +6 \
    | cut -f2- \
    | xargs -r r

0

আইজ্যাক ফ্রিম্যানের প্রতিক্রিয়ার ভিত্তিতে, তবে যে কোনও ডিরেক্টরিতে কাজ করছেন:

ls -1tr $PATH_TO_DELETE/* | head -n -10 | xargs -d '\n' rm -f --

আপনি যেমন উপসর্গ সেট করতে পারেন $PATH_TO_DELETE/testFi*

আপনি যদি উইলের *পরে PATH lsনিখুঁত ফাইলের নামগুলি আউটপুট ব্যবহার করেন তবে কমপক্ষে "আমার" বাশে :)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.