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


16

আমার folderAকাছে কিছু ফাইল রয়েছে যার সাথে একটি নম্বর ক্রম শুরু হচ্ছে a_000000। আমি যা করতে চাই তা হ'ল একটি নির্দিষ্ট নম্বর থেকে শুরু হওয়া ফাইলগুলি মুছে ফেলা: আসুন এর a_000750মধ্যে ফাইলগুলির শেষ হওয়া পর্যন্ত বলা যাক folderA। কেউ দয়া করে কীভাবে শেল স্ক্রিপ্ট ব্যবহার করে এটি করতে পরামর্শ দিতে পারেন?


আমি কি ধরে নিতে পারি যে এই সমস্ত ফাইলের নামের 6-সংখ্যার প্রত্যয় আছে?
মুরু

হ্যাঁ তারা হ'ল: তারা a_000000 থেকে শুরু করে কিছু সংখ্যক অবধি
তাক

5
rm a_000[89]* a_0007[5-9]*?
রিনজউইন্ড

@ রিনজুইন্ড আপনি কি এই আদেশটি ব্যাখ্যা করতে পারবেন?
তাক

2
@ user1460166 a_000[89]*প্রতি ফাইল শুরুতে অন্তর্ভুক্ত a_0008বা a_0009, এবং a_0007[5-9]*শুরু প্রতিটি ফাইল অন্তর্ভুক্ত a_0007এবং তারপর 5 এবং 9 এর মধ্যে একটি সংখ্যা, কিছু দ্বারা অনুসরণ রয়েছে।
মুরু

উত্তর:


35

ধরে নিচ্ছি যে আপনি জানেন বা রেঞ্জের শেষটি অনুমান করতে পারেন, আপনি ব্রেস বিস্তৃতি ব্যবহার করতে পারেন :

rm a_{000750..000850}

উপরেরগুলি 101_ ফাইলগুলিকে a_000750 এবং a_000850 সমেত অন্তর্ভুক্ত করবে (এবং ফাইল-নামগুলি সম্পর্কে অভিযোগ করবে যা অস্তিত্বের ফাইলগুলি উল্লেখ করে)। যদি এর জন্য আপনার কাছে খুব বেশি ফাইল থাকে তবে ব্যবহার করুন find:

find . -name 'a_*' | while read file; do 
  [ "${file#./a_}" -gt 000749 ] && rm -v "$file" 
done

এখানে, findকেবল সমস্ত ফাইলের সাথে মিলে যাওয়া তালিকাবদ্ধ করে a_*। তালিকা একটি প্রেরণ করা whileলুপ যেখানে প্রতিটি ফাইলের নাম পরিবর্তনশীল মধ্যে পড়া হয় $file। তারপরে, বাশের স্ট্রিং ম্যানিপুলেশন বৈশিষ্ট্যগুলি ব্যবহার করে, যদি সংখ্যার অংশ (যেমন প্রিন্টগুলি ফাইলগুলি সন্ধান করুন ./file, ${file#./a_}কেবলমাত্র সংখ্যাটি প্রিন্ট করে) হয় 000750বা বেশি হয়, ফাইলটি মুছে ফেলা হয়। -vঠিক আছে, তাই আপনি তা দেখতে পারেন ফাইল সরানো হয়েছে।

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

find . -name 'a_*' -print0 | while IFS= read -rd '' file; do 
  [ "${file#./a_}" -gt 000749 ] && rm -v "$file" 
done

কেন এড়াবেন [[?
মুরু

1
@ মুরু কেন এটি ব্যবহার করবেন? উদাহরণস্বরূপ [[এখানে জিনিসগুলি সরল [[ "${file#./a_}" > 000749 ]]করে না, এমনকি এটি কোনও ছোটও করে না। আমি অপ্রয়োজনীয় বাক্য গঠন ব্যবহার করতে পছন্দ করি না এবং এটি এমনকি সহজ শেলগুলিতেও কাজ করবে dash
টেরডন

কারণ [[স্পেস এবং অদ্ভুততাগুলি আরও ভালভাবে পরিচালনা করে (আমি >উভয়ের পক্ষে খুব বেশি যত্ন করি না )।
মুরু

1
@ মুরু হ্যাঁ, তবে [আপনি যদি আমার মতো চলকটি উদ্ধৃত করেন তবে তা ঠিক আছে, আরও বেশি শেলগুলিতে কাজ করে এবং আরও সহজ।
টেরডন

জিদ দিলে। আমার সমস্যা না.
মুরু

3

আপনি এরকম কিছু করতে পারেন:

find . -regextype posix-extended -iregex './a_[0-9]{6}' -execdir bash -c '[[ ${1##./a_} > 000750 ]] && echo $1' "removing: " {} \;

বা:

find . -regextype posix-extended -iregex './a_[0-9]{6}' | sort | sed '0,/000750/d' | xargs echo

প্রথম পদ্ধতিটি একটি নির্দিষ্ট উপসর্গ ধরে নেয়, এটিকে সরিয়ে দেয় এবং মানটি পরীক্ষা করে।

দ্বিতীয় পদ্ধতিটি একটি নির্দিষ্ট দৈর্ঘ্যের প্রত্যয় (এবং একটি সাধারণ নির্দিষ্ট উপসর্গ) ধরে নেয় এবং এই সত্যের উপর নির্ভর করে; এবং এটি, অভিধানের 201আগে আসার আগে 31, এটি আগে হয় না 031

echoকমান্ডটি দিয়ে এটি পরীক্ষা করুন এবং একবার নিশ্চিত হয়ে নিন যে এটি সঠিক ফাইলগুলি তালিকাভুক্ত করেছে, rmপরিবর্তে ব্যবহার করুন।


তাদের মধ্যে কেউই কাজ করছে না: /
তাক

@ ব্যবহারকারী 1460166 হ্যাঁ, এটি সম্ভবত রেজেক্সের মিলের কারণে। আমি এটি আপডেট করব।
মুরু

এখনও কাজ করছে না. বিটিডব্লিউ, ফাইলগুলি .png :)
তাক

@ user1460166 আপনি কীভাবে এটি কাজ করছেন না বলতে পারেন?
মুরু

আমি টার্মিনালটি খুলি, ফোল্ডারে সিডি করব তারপরে আপনার লাইনটি অনুলিপি করুন এবং এটি আটকে দিন তবে ফাইলগুলি মুছে ফেলা হয় না
Tak

0

পসিক্স শেল দ্রবণ

টার্ডনের প্রথম সমাধানটি ব্রেস প্রসারণের উপর নির্ভর করে, যা একটি সম্পত্তি bashএবং kshতবে এটি স্ট্যান্ডার্ড /bin/shশেলটিতে ব্যবহার করা যাবে না , যা উবুন্টুতে অনুরূপ /bin/dash

/bin/shআপনার স্ক্রিপ্টগুলির বহনযোগ্যতার জন্য আপনাকে নির্ভর করতে হবে এমন ক্ষেত্রে, সাধারণত এটির কাছে যাওয়ার দুটি উপায় রয়েছে। এক গ্লোববিংয়ের মাধ্যমে হবে। শুধু cd folderAএবং সেখান থেকে চালান rm a_*। অন্য উপায়টি হ'ল while <CONDITION>;do ...doneশেল ল্যাঙ্গুয়েজে লুপ বিকল্পের জন্য সি-স্টাইল প্রয়োগ করা এবং এর সাথে সংখ্যার বিন্যাস করা printf:

$ sh -c 'i=0;while [ $i -le 750 ]; do filename=$(printf "a_%06d" $i);echo "$filename";i=$((i+1)) ;done'

আমি এখানে ব্যবহার লক্ষ্য করুন echo। আপনি ফাইলগুলি মুছতে প্রস্তুত বা এর echo "$filename"সাথে প্রতিস্থাপন করুন । এছাড়াও নোট করুন, আপনি ইতিমধ্যে পছন্দসই ডিরেক্টরিতে এড করার সময় এটি করা উচিত ।rm ./"$filename"rm -- "$filename"cd

(অব) অ্যাজক ব্যবহার করে

আউক একটি দুর্দান্ত সি-এর মতো ভাষা হওয়ায় আমাদের দুটি উপায়ে সহায়তা করতে পারে: (১) আমরা ফর্ম-লুপের সাথে ফাইলের নাম তৈরি করতে পারি এবং sprintfফাংশনের মাধ্যমে সেগুলি ফর্ম্যাট করতে পারি এবং (২) system()কমান্ডের মাধ্যমে বলা ফাইলগুলি মুছুন , যা আমাদের উত্পন্ন ফাইলের নাম এবং rmকমান্ডটি পাস করবে থেকে /bin/sh:

awk 'BEGIN{for(i=0;i<=750;i++){filename=sprintf("a_%06d",i);system("rm "filename);} }'

পার্ল

পোর্টেবল পদ্ধতির ধারণার সাথে অবিরত যেখানে আমরা ফাইলের নামগুলি "উত্পন্ন" করি, আমরা পার্লেও এটি করতে পারি:

perl -le 'for(0..750){$fd=sprintf("a_%06d",$_);unlink($fd)}'

0

মতই সহজ

rm partialfilename* -f

আপনার উদাহরণে এটি

rm a_00075* -f

1
a_00075
দুঃখের

1
* একটি ওয়াইল্ডকার্ড, ওপি কীভাবে কোনও রেঞ্জের জিনিসগুলি মুছবেন তার একটি উত্তর খুঁজছেন ... উদাহরণস্বরূপ যদি আপনার কাছে 1 থেকে 100 ফাইল রয়েছে এবং # 41 থেকে # 75 মুছতে চান
জোশুয়া বেসিনিট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.