একটি ডিরেক্টরিতে সমস্ত ফাইল মুছুন যার নাম ফাইল তালিকার কোনও লাইনের সাথে মেলে না


9

আমার কাছে 1000+ ফাইল সহ একটি ডিরেক্টরি রয়েছে। একটি পাঠ্য ফাইলে আমার কাছে প্রায় 50 টি ফাইলের নাম রয়েছে, প্রতি লাইনে একটি করে। আমি ডিরেক্টরিতে থাকা সমস্ত ফাইল মুছতে চাই যার ফাইলের নাম তালিকার কোনও প্রবেশের সাথে সামঞ্জস্য করে না। এটি করার সর্বোত্তম উপায় কী? আমি একটি শেল স্ক্রিপ্ট শুরু করেছি, তবে তালিকাতে ফাইলের নাম নির্ধারণের জন্য সঠিক কমান্ডটি নির্ধারণ করতে পারিনি। ধন্যবাদ।

উত্তর:


8

আমি বুঝতে পেরেছি যে ফাইলগুলি কীভাবে মুছতে হয় তা জিজ্ঞাসা করার কোনও প্রশ্ন অবশ্যই খুব যত্ন সহকারে নেওয়া উচিত। আমার প্রথম উত্তরটি খুব তাড়াহুড়োয় ছিল আমি ফাইললিস্টটি উদাহরণস্বরূপ ব্যবহারের জন্য বিকৃত হতে পারে take আমি সেই ঝুঁকি কমাতে উত্তরটি সম্পাদনা করেছি।

যে নামে ফাইল নেই তার পক্ষে কাজ করা উচিত:

সঠিক ফাইলের নামের সাথে মেলে নিশ্চিত হওয়ার জন্য প্রথমে আপনার ফাইললিস্টটি পুনর্নির্মাণ করুন:

sed -e 's,^,^,' -e 's,$,$,'  filelist  > newfilelist 

আরএম কমান্ড তৈরি করুন

cd your_directory
ls | egrep -vf newfilelist   | xargs -n 1 echo rm  >  rmscript

আরএম স্ক্রিপ্টটি আপনার উপযুক্ত কিনা তা পরীক্ষা করুন (আপনি এটি "ভিএম" বা "কম" দিয়ে করতে পারেন)।
তারপরে ক্রিয়াটি সম্পাদন করুন:

sh -x rmscript

যদি ফাইলগুলির নামে স্পেস থাকে (যদি ফাইলগুলির "নামে থাকে তবে এটি কাজ করবে না):

ls | egrep -vf newfilelist  | sed 's,^\(.*\)$,rm "\1",' > rmscript

অবশ্যই ফাইললিস্ট একই ডিরেক্টরিতে থাকা উচিত নয়!

সম্পাদিত:

নাথানের ফাইল তালিকায় এমন নাম রয়েছে যা ডিরেক্টরিতে থাকা সমস্ত ফাইলের সাথে মিলছিল (যেমন "এইচটিএমএল" "বব এইচটিএমএল" মেলে)। সুতরাং কিছুই মুছে ফেলা হয়নি কারণ egrep -vfসমস্ত স্ট্রিম শোষণ করে। আমি প্রতিটি ফাইলের নামের চারদিকে একটি "^" এবং একটি "$" রাখতে একটি কমান্ড যুক্ত করেছি। আমি এখানে ভাগ্যবান যে নাথানের ফাইল তালিকাটি সঠিক ছিল। এটি কি সিআর-এলএফ সমাপ্ত লাইনের সাথে বা অতিরিক্ত স্পেস সহ ডস ফর্ম্যাট করা হত, কোনও ফাইল এগ্রেপ দ্বারা সংরক্ষণ করা হত না এবং সমস্ত মুছে ফেলা হত।


আমি যখন প্রাকদর্শন কমান্ডটি চালাচ্ছি তখন আমি "আরএম" দিয়ে একটি লাইন পাই। আমি যখন আসল কমান্ডটি চালাচ্ছি তখন আমি আরএম এর জন্য অনুপস্থিত যুক্তি সম্পর্কে ত্রুটি বার্তা পাই। Ls থেকে ফলাফলগুলি ব্যবহার করার জন্য আমার কি বিশেষ সিনট্যাক্স দরকার? xargs ইনপুট মধ্যে egrep?
নাথান

@ নাথান আপনাকে প্রথমে আপনার ডিরেক্টরিতে সিডি করতে হবে। কোনও বিশেষ সিনটেক্সট নেই। lsডিরেক্টরি ফাইলের নাম সরবরাহ করে, egrep -vf filelistআপনার 50 টি ফাইলের নাম ফিল্টার করে। আমি ভয় করি আপনি আপনার সমস্ত ফাইল মুছে ফেলেছেন।
এমানুয়েল

@ ইমানুয়েল আমি যে ডিরেক্টরিটি মুছতে হবে সেগুলি থেকে কমান্ডটি চালাচ্ছি।
নাথান

@ নাথান আপনার সমস্ত ফাইল মুছে ফেলা হয়েছে?
এমমানুয়েল

না, তারা এখনও আছে।
নাথান

1

এখানে যুক্তিগুলি প্রাক-নির্মাণ করুন find:

{
  read -r
  keep=( -name "$REPLY" ) # no `-o` before the first one.
  while read -r; do
    keep+=( -o -name "$REPLY" )
  done
} < file_list.txt
find . -type f ! \( "${keep[@]}" \) -exec echo rm {} +

echoকি নির্মাণ করা হবে তা দেখতে অংশগুলি ব্যবহার করুন । echoএটি চালানোর জন্য অংশগুলি সরান ।

আপডেট: বিক্ষোভ:

##
# Demonstrate what files exist for testing.
# Show their whitespace:
~/foo $ printf '"%s"\n' *
" op"
" qr"
"abc"
"def"
"gh "
"ij "
"k l"
"keep"
"m n"

##
# Show the contents of the "keep" file,
# Including its whitespace:
~/foo $ cat -e keep
keep$
abc$
gh $
k l$
 op$

##
# Execute the script:
~/foo $ { read -r; keep=( -name "$REPLY" ); while read -r ; do keep+=( -o -name "$REPLY" ); done } < keep
~/foo $ find . -type f ! \( "${keep[@]}" \) -exec rm {} +

##
# Show what files remain:
~/foo $ printf '"%s"\n' *
" op"
"abc"
"gh "
"k l"
"keep"


আমার কাছ থেকে +1, যদিও এটি স্পেসগুলির সাথে খুব ভাল আচরণ করে না। সম্ভবত কিছু একক উদ্ধৃতি ( ') যুক্ত করা উচিত অর্থাত keep=( -name \'"$REPLY"\' )এবং এবং keep+=( -o -name \'"$REPLY"\' )
ক্রিশ্চিয়ান সিউপিতু

উপরেরটি বিপজ্জনক, কারণ আপনি দুর্ঘটনাক্রমে ফাইলগুলি মুছতে পারেন।
ডেভিডভা

পছন্দ করেছেন আমি একটি ডেমো যুক্ত করে দেখিয়েছি যে এটি সাদা জায়গার সাথে খুব ভালভাবে ডিল করে।
কোজিরো

@ ডেভিডভা কোন পরিস্থিতিতে? যে কোনও সময় আপনি কোনও ভুল করার ঝুঁকিটি চালান এমন জিনিসগুলি মোছার স্বয়ংক্রিয়ভাবে ব্যবহার করলেও আমার মনে হয় যে প্রশ্নটির প্যারামিটারের মধ্যে আমার ডেমো প্রমাণ করে যে এই পদ্ধতির শব্দটি দৃ is়।
কোজিরো

1

সহ zsh:

mylist=(${(f)"$(<filelist)"})
print -rl -- *(.^e_'(($mylist[(Ie)$REPLY]))'_)

এটি filelistঅ্যারে রেখাগুলি পড়বেe এবং তারপরে গ্লোব কোয়ালিফায়ার / স্ট্রিং ব্যবহার করে গ্লোব করতে / অ্যারেতে উপস্থিত না থাকা কেবলমাত্র ফাইলের নাম .নির্বাচন করুন: কেবলমাত্র নিয়মিত ফাইলগুলি নির্বাচন করে ( Dআপনার তালিকায় ডটফাইল রয়েছে তবে যোগ করুন ) এবং অবহেলিত ^e_'expression'_আরও কেবল সেইগুলির জন্য নির্বাচন করে যা অভিব্যক্তিটি মিথ্যা প্রত্যাবর্তন করে, অর্থাত্ যদি তাদের নাম ( $REPLY) অ্যারের উপাদান না হয়
আপনি ফলাফল নিয়ে খুশি থাকেন প্রতিস্থাপন print -rlসঙ্গে rmআসলে ফাইল মুছে ফেলুন করুন:

rm -- *(.^e_'(($mylist[(Ie)$REPLY]))'_)

পুনরাবৃত্তভাবে ফাইলগুলি নির্বাচন এবং অপসারণ করতে, গ্লোব সংশোধক */**সহ ${REPLY:t}গ্লোব ব্যবহার করুন :

rm -- */**(.^e_'(($mylist[(Ie)${REPLY:t}]))'_)

0

যদি আপনি ডিরেক্টরিটির বিষয়বস্তুগুলিকে কোনও ফাইলে রাখেন:

cd <somedirectory>
ls >> filelist

একটি টেক্সট এডিটর দিয়ে ওপেন FileList, এবং বেশী ছাড়া সমস্ত ফাইল মুছে ফেলুন আপনি মুছে ফেলতে চান । এটি গা bold় কারণ এটি উপরের উত্তরের বিপরীত পদ্ধতি

এটা চেষ্টা কর:

while read p || [[ -n $p ]]; 
echo $p
done < filelist

আপনি যদি স্ক্রিনে আপনার ফাইলগুলির আউটপুটের তালিকাটি প্রতিস্থাপন করেন তবে এর মতো প্রতিধ্বনি প্রতিস্থাপন করুন rm -v:

while read p || [[ -n $p ]]; 
rm -v $p
done < filelist

0

নীচের স্ক্রিপ্টটি চালান।

  1. প্রাথমিকভাবে আমি ডিরেক্টরিতে উপস্থিত সমস্ত ফাইল সন্ধান করছি এবং আউটপুটটিকে অন্য একটি ফাইলে সংরক্ষণ করছি all_files
  2. আমাদের একটি ফাইল রয়েছে যা ফাইলগুলির তালিকা রয়েছে যা মুছে ফেলা উচিত নয় ( not_to_be_deleted_files)।
  3. আমি ফাইলের নামগুলি not_to_be_deleted_filesএবং files_to_be_deletedশেষ not_to_be_deleted_filesহিসাবে এই 2 টি ফাইলের প্রয়োজন যুক্ত করছি need
  4. এখন, আমি লিনাক্স joinকমান্ড ব্যবহার করে মুছে ফেলার প্রয়োজনীয় ফাইলগুলি খুঁজে বের করছি এবং আউটপুটটিকে files_to_be_deleted ফাইলটিতে পুনর্নির্দেশ করব ।
  5. এখন, ফাইনালের সময় আমি সমস্ত ফাইলের নামটি পড়ছি files_to_be_deletedএবং সেই ফাইলের নামটিতে উল্লিখিত ফাইলগুলি সরিয়ে ফেলছি।

স্ক্রিপ্টটি নীচে রয়েছে।

find /home/username/directory -type f | sed 's/.*\///' > all_files
echo all_files >> not_to_be_deleted_files
echo not_to_be_deleted_files >> not_to_be_deleted_files
echo files_to_be_deleted >> not_to_be_deleted_files
join -v 1 <(sort all_files_listed) <(sort files_not_to_be_deleted) >   files_to_be_deleted
while read file
rm  "$file"
done < files_to_be_deleted

পিএস : সম্ভবত, আপনি যদি এটি একটি স্ক্রিপ্ট হিসাবে সংরক্ষণ করে চালাতে চান, আপনি স্ক্রিপ্টের নামটিও যুক্ত করে যুক্ত করতে পারেন echo scriptname >> not_to_be_deleted_files

যদিও এটি প্রয়োজন হয় না, আমি এটি করতে পছন্দ করি কারণ পরে কোনও অনুশোচনা হবে না। আমি ফাইলগুলির একটি ছোট সেট পরীক্ষা করেছি এবং এটি আমার সিস্টেমে কাজ করে। তবে আপনি যদি নিশ্চিত হতে চান তবে testপ্রথমে একটি ডিরেক্টরিতে চেষ্টা করুন এবং তারপরে মূল ডিরেক্টরিতে থাকা ফাইলগুলি সরিয়ে দিন।


0
  • তালিকার সমস্ত ফাইলকে একটি নতুন, নতুন এবং খালি সেভ-ডায়ারে সরানোর জন্য উত্স হিসাবে তালিকাটি ব্যবহার করুন।
  • তালিকার ফাইলগুলির সংখ্যা এবং সেভ করা ফাইলের সংখ্যার সাথে তুলনা করুন।
  • যদি উভয়ই মিলে যায় তবে আপনার প্রিয় পদ্ধতির সাহায্যে সমস্ত সংরক্ষিত ফাইল মুছুন।
  • সংরক্ষিত ফাইলগুলি আবার সরিয়ে দিন।

0

আমি একটি নিরাপদ এবং আরও অনেক দ্রুত পদ্ধতির জন্য গিয়েছিলাম কারণ তালিকায় আমার 18.000 ফাইল রয়েছে! একটি বড় ড্রুপাল ইনস্টলেশনতে আমার ছবিগুলি পরিষ্কার করা দরকার।

তালিকায় নেই এমন সমস্ত ফাইল মুছে ফেলা কেবল তালিকায় থাকা ফাইলগুলি রাখার মতোই। সুতরাং আমি সিদ্ধান্ত নিয়েছিলাম যে তালিকাটি ফাইল থেকে অন্য স্থানে অনুলিপি করার চেষ্টা করেছি, তবে ২০ জিবি ফাইল অনুলিপি করাতে খুব বেশি জায়গা লাগবে এবং পাশাপাশি খুব ধীর হয়ে যাবে। কৌশলটি হ'ল বিকল্পটি বিকল্পটি hardlinksব্যবহার করে তার পরিবর্তে ফাইলগুলি অনুলিপি করা । এটি প্রায় কোনও স্থান নেয় এবং খুব দ্রুত is অতিরিক্ত হিসাবে, যেহেতু আমার ডিরেক্টরি কাঠামো সংরক্ষণ করার প্রয়োজন ছিল তাই আমি বিকল্পটি ব্যবহার করেছি ।-lcp--parents

আমার ফাইল তালিকার একটি অংশ এখানে দেওয়া হয়েছে:

1px.png
misc/feed.png
modules/file/icons/x-office-presentation.png
modules/file/icons/x-office-spreadsheet.png
newsletter.png
sites/all/libraries/ckeditor/plugins/smiley/images/devil_smile.png
sites/all/libraries/ckeditor/plugins/smiley/images/regular_smile.png
sites/default/files/009313_PwC_banner_CBS_Observer_180x246px.jpg

সুতরাং একটি উদাহরণ লাইন হবে অস্থায়ী গন্তব্য হিসাবে:

cp -l --parents 'misc/feed.png' temp

এটি এই কাঠামো তৈরি করবে:

temp
  misc
    feed.png

নোট করুন যে হার্ডলিঙ্কগুলি কাজ করার জন্য উত্স হিসাবে ডেসটিন্যাটন অবশ্যই একই ফাইল সিস্টেমে থাকতে হবে।

পরবর্তী পদক্ষেপটি স্ক্রিপ্টটি নির্মাণ করা হয়:

sed -e "s,^,cp -l --parents '," -e "s,$,' /some/where/temp," filelist > newfilelist

এখন ধরে নেওয়া, আপনি ইতিমধ্যে খালি দির / কিছু / যেখানে / টেম্প তৈরি করেছেন, আপনি ফাইলগুলি অনুলিপি করতে পারেন:

sh newfilelist 2> missing_files

ত্রুটিগুলি কীভাবে শেষ হয় তা নোট করুন missing_files। এই পদ্ধতির অতিরিক্ত বোনাস যে আপনি আসল তালিকা যে আসলে থেকে ফাইল সম্বন্ধে জানতে-- হবে না থাকবেই!

স্ক্রিপ্টটি চালানোর পরে, টেম্পে কেবলমাত্র সেই ফাইলগুলি অন্তর্ভুক্ত থাকবে যা ফাইল তালিকার মধ্যে রয়েছে তবে কোনও কিছু মোছা ছাড়াই এবং অতিরিক্ত স্থান না নিয়ে। আপনি যদি ফলাফলটির সাথে সন্তুষ্ট হন তবে আপনি সাবফোল্ডারগুলি সহ সমস্ত অরজিনাল ফাইলগুলি মুছতে পারেন।

শেষ পর্যন্ত, ফাইল এবং ফোল্ডারগুলি অস্থায়ী থেকে মূল অবস্থানে ফিরে যান।

18.000 ফাইলের জন্য এটি কয়েক সেকেন্ড সময় নিয়েছিল।


0

নিরাপদ, সহজ।

cd ডিরেক্টরিতে।

একটি অস্থায়ী ডিরেক্টরি তৈরি করুন।

mv *.yourExlusionSelector.* ./temp
rm *
mv ./temp ./
rm -rf ./temp

সম্পন্ন.


সাইটে স্বাগতম। আপনার দৃষ্টিভঙ্গি যদি কাজ করে তবে ওপি দ্বারা উল্লিখিত তালিকার নামগুলি একটি সাধারণ প্যাটার্ন মিলের ফলাফল - যা খুব ভাল ক্ষেত্রে হতে পারে - দয়া করে নোট করুন যে ওপি বলেছে যে বাদ দেওয়া ফাইলের নামগুলি একটি নির্দিষ্ট ফাইলে সংরক্ষণ করা হয়েছে; আপনি আপনার উত্তরটি প্রসারিত করতে চাইতে পারেন যাতে কোনও স্থিতিশীল প্যাটার্নের উপর নির্ভর না করে বা কনসোলে সম্ভাব্য একাধিক নিদর্শনগুলি টাইপ-অনুলিপি করে ফাইল থেকে বাদ পড়ার ধরণগুলি পড়তে পারে।
অ্যাডমিনবি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.