টার্মিনাল থেকে একটি ফাইল বাদে একটি নির্দিষ্ট এক্সটেনশন সহ ফাইলগুলি সরানো


36

আমাকে "ফাইলের নাম.gif" নামের একটি ফাইল বাদে .gif এক্সটেনশনের সমস্ত ফাইল সরিয়ে ফেলতে হবে। টার্মিনালে এটি করার সর্বোত্তম উপায় কী?

Rm কমান্ড *.gifফাইল সহ সমস্ত জিআইএফ ফাইল সরিয়ে দেয় filename.gif

উত্তর:


66

আপনার সম্ভবত ব্যবহার করা উচিত এমন সহজ সমাধানটি এখানে:

mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif

.keepএক্সটেনশন সম্পর্কে বিশেষ কিছুই নেই , এটি কেবল এটি তৈরি করে যাতে ফাইলের নাম অস্থায়ীভাবে শেষ না হয় .gif

যদি আপনার অবশ্যই ফাইলটির নাম পরিবর্তন না করা হয় (এবং স্ক্রিপ্টিং পরিস্থিতি যেখানে এটি গুরুত্বপূর্ণ):

for X in *.gif; do
    if [ "$X" != "filename.gif" ]; then
        rm "$X"
    fi
done

অথবা আপনি এটিকে আরও ছোট করে লিখতে পারেন:

for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done

findপরিবর্তে আপনি ব্যবহার করতে পছন্দ করতে পারেন ; এটি খুব শক্তিশালী, আপনি এটিকে আরও পঠনযোগ্য বলে মনে করতে পারেন এবং এটির মতো অক্ষরের সাথে অদ্ভুত ফাইলের নামগুলি* ভালভাবে পরিচালনা করে

find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete

আমি -notঅপারেটরটিকে পঠনযোগ্যতার জন্য ব্যবহার করেছি , তবে পসিক্স সম্মতি যদি গুরুত্বপূর্ণ হয় - আপনি যদি জিএনইউ অনুসন্ধান ব্যবহার না করে থাকেন, বা যদি এটি কোনও স্ক্রিপ্টের জন্য হয় যা আপনি অন্যদের কাছে পুনরায় বিতরণ করতে চান বা বিভিন্ন সিস্টেমে চালনা করতে চান - আপনার উচিত ব্যবহার !পরিবর্তে অপারেটর:

find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete

একটি সহজ বিষয় findহ'ল আপনি সহজেই কেস-সংবেদনশীলতার জন্য কমান্ডটি সংশোধন করতে পারেন, যাতে এটি এক্সটেনশন সহ ফাইলগুলি সন্ধান এবং মুছে ফেলতে .GIFপারে:

find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete

দয়া করে মনে রাখবেন যে, আমি ব্যবহার করেছি -inameস্থানে -nameঅনুসন্ধান প্যাটার্ন জন্য *.gifকিন্তু আমি করেছি না যাবত ব্যবহার করেন filename.gif। সম্ভবত আপনি জানেন যে আপনার ফাইলটি কী বলা হয়, এবং -inameকেবলমাত্র এক্সটেনশনে নয় , ফাইলের নামের যে কোনও জায়গায় বিকল্প মূলধনের সাথে মিলবে ।

এই সব সমাধান শুধুমাত্র ডিলিট বর্তমান ডিরেক্টরির মধ্যে অবিলম্বে অবস্থিত ফাইলগুলি । তারা বর্তমান ডিরেক্টরিতে অন্তর্ভুক্ত থাকা ফাইলগুলি মুছবে না এবং বর্তমান ডিরেক্টরিটির সাব-ডিরেক্টরিতে থাকা ফাইলগুলি তারা মুছবে না।

আপনি যদি বর্তমান ডিরেক্টরিতে অন্তর্ভুক্ত রয়েছে এমন ফাইলগুলি মুছে ফেলতে চান (এটি হ'ল সাব-ডাইরেক্টরিগুলিতে এবং সেই উপ-ডিরেক্টরিগুলির উপ-ডিরেক্টরিগুলিতে, এবং আরও - বর্তমান ডিরেক্টরি বা এর বংশধরের যে কোনও ফাইলের মধ্যে থাকা ফাইলগুলি) find ব্যতীত ব্যবহার করুন maxdepth -1:

find . -not -name 'filename.gif' -name '*.gif' -delete

এই সাবধান!

এছাড়াও আপনি অন্যান্য মান সেট করতে পারেন -maxdepth। উদাহরণস্বরূপ, বর্তমান ডিরেক্টরিতে ফাইলগুলি এবং তার শিশু এবং নাতি নাতনিদের মুছতে তবে আরও গভীর নয়:

find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete

কেবলমাত্র নিশ্চিত হয়ে নিন যে আপনি কখনই -deleteপ্রথম প্রকাশ করেন নি, অন্যান্য অভিব্যক্তিগুলির আগে! আপনি দেখতে পাবেন আমি সবসময় -deleteশেষে রেখেছি । আপনি যদি এটি শুরুতে রাখেন তবে প্রথমে এটি মূল্যায়ন করা হবে এবং এর অধীনে থাকা সমস্ত ফাইল .(শেষ হয় না এমন .gifফাইলগুলি এবং গভীর সাব-সাব-সাব ... ডিরেক্টরিগুলির ফাইলগুলি .) মুছে ফেলা হবে!

আরও তথ্যের জন্য , জন্য ম্যানুয়াল পৃষ্ঠা দেখুন bashএবং shএই উদাহরণ মধ্যে ব্যবহৃত কমান্ডগুলির জন্য: mv, rm, [, এবং (বিশেষত) find


1
ধন্যবাদ এলিয়াহ। আপনার প্রস্তাবিত প্রথম পদ্ধতির মতোই আমি এটি করেছি অর্থাৎ ফাইলটিকে অন্য কোনও ফর্ম্যাটে রূপান্তর করতে এবং এটিকে আবার রূপান্তর করতে। তবে এটি কিছুটা উপ-অনুকূল এবং অপরিষ্কার বলে মনে হয়েছিল। আপনি এবং @fthialex আপনাকে যে দ্বিতীয় পদ্ধতির পরামর্শ দিয়েছেন এবং আমি এটি এখন ব্যবহার করছি তা পছন্দ করি। ধন্যবাদ!

1
@ মারভিস আমি আপনার প্রয়োজন মেটাতে পেরে আনন্দিত। যাইহোক, আমি এই উত্তরটি অন্য পদ্ধতি (বা পদ্ধতির শ্রেণি) ব্যবহার করে তথ্যটি প্রসারিত করেছি find, যা অত্যন্ত বহুমুখী।
এলিয়াহ কাগন

3
বিস্তারিত উত্তরের জন্য ধন্যবাদ findসত্যিই একটি ভাল ফলাফল।

1
কমনসেন্স (মুভ-মুছুন-মুভ) উত্তরের জন্য +1।
ইনস্টল করুন মনিকা-ডোর দুহ

নীট-বাছাই: কীভাবে অজানা findফাইলের নামগুলি এতে *লুপের চেয়ে ভাল হ্যান্ডেল করে ? লুপটি ফাইলগুলি *সূক্ষ্মভাবে পরিচালনা করে , কারণ আপনি ডাবল উদ্ধৃতি ব্যবহার করেছেন।
ফ্লিম

28

আপনি যদি bash(ডিফল্ট শেল) ব্যবহার করেন তবে extglobশেল বিকল্পটি আপনাকে একটি বর্ধিত প্যাটার্ন মেলানো সিনট্যাক্স ব্যবহার করতে দেয়। এটি সক্ষম করতে, shoptবিল্টিন কমান্ডটি ব্যবহার করুন :

shopt -s extglob

(আমি আমার .bashrcফাইলে সেই লাইনটি অন্তর্ভুক্ত করেছি ))

অন্যান্য জিনিসের মধ্যে এটি !()অপারেটরের অ্যাক্সেসকে মঞ্জুর করে , যা পেরেনগুলির মধ্যে নয় এমন কোনও প্যাটার্নের সাথে মেলে। আপনার উদ্দেশ্যে:

rm !(filename).gif

man bash"প্যাটার্ন ম্যাচিং" এর অধীনে আরও তথ্য পাওয়া যায় ।


1
দুর্দান্ত উত্তর! এটি ব্যাশ-নির্দিষ্ট তাই পোর্টেবল স্ক্রিপ্টিংয়ের জন্য উপযুক্ত নাও হতে পারে তবে ইন্টারেক্টিভ কাজগুলি এবং কিছু স্ক্রিপ্টিংও এটি হ'ল ডাউন-যাবার সেরা উপায়। এটি এমন অতিরিক্ত জটিলতা বহন করে যা extglobঅবশ্যই সক্ষম করা উচিত, তবে এটি অক্ষম হলে খারাপ কিছু হয় না ( সেক্ষেত্রে এটি কেবল কাজ করে না)। এবং এটি আমার ডিফল্টরূপে সক্ষম হয়েছে বলে মনে হয়, যদিও shopt -s extglobআমার (বা বিশ্বব্যাপী) কনফিগারেশন ফাইলগুলির কোনও আমার কাছে নেই। এটি কেন বাক্স থেকে আমার জন্য কাজ করে তার একটি সহজ ব্যাখ্যা থাকলে, আপনি এটি এই উত্তরে যুক্ত করতে চাইতে পারেন; বা আমি একটি নতুন প্রশ্ন পোস্ট করতে পারেন।
এলিয়াহ কাগন

13

একটি খোলা টার্মিনাল সঙ্গে Ctrl+ + Alt+ + Tএবং টাইপ:

find . -type f -name "*.gif" -and -not -name "filename.gif" -exec rm -vf {} \;

-deleteএবং এর মধ্যে পার্থক্যটি -exec rm -vf {} \;হ'ল দ্বিতীয় বিকল্পের সাহায্যে, আপনি -vপতাকাটির কারণে কোন ফাইলগুলি সরানো হয়েছে তা দেখতে সক্ষম হবেন । এটি এমন কিছু যা -deleteবিকল্পের সাহায্যে করা যায় না । ( -name -deleteফাইলের নামের প্রিন্ট হবে, কিন্তু rmসঙ্গে -vপ্রকাশ করে যদি প্রতিটি ফাইল ছিল সফলভাবে মোছা হয়েছে।)


1

আছে GLOBIGNOREপরিবর্তনশীল। থেকে man bash:

GLOBIGNORE
      A colon-separated list of patterns defining the set of filenames
      to be ignored by pathname expansion.  If a filename matched by a
      pathname expansion pattern also matches one of the  patterns  in
      GLOBIGNORE, it is removed from the list of matches.

সুতরাং, একটি সহজ উপায় হ'ল GLOBGINOREপ্রশ্নে থাকা ফাইলের নামটিতে সেট করা:

$ touch {a,b,c,d}.png
$ echo *.png
a.png b.png c.png d.png
$ GLOBIGNORE=c.png
$ echo *.png
a.png b.png d.png

সুতরাং, আপনার ক্ষেত্রে:

GLOBIGNORE=filename.gif; rm *.gif

অবশ্যই, যেহেতু GLOBIGNOREনিদর্শনগুলি রয়েছে, আপনি যখনই কোনও প্যাটার্নটি বাদ দিতে চান আপনি এটি ব্যবহার করতে পারেন:

$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png

এর একটি সুবিধা (?!) GLOBIGNOREহ'ল সেটিংসটি স্বয়ংক্রিয়ভাবে বাদ যায় .এবং.. মিল হয় না এবং এটি সক্ষম করে dotglob:

The  GLOBIGNORE shell variable may be used to restrict the set of file‐
names matching a pattern.  If GLOBIGNORE is set, each matching filename
that also matches one of the patterns in GLOBIGNORE is removed from the
list of matches.  The filenames ``.''  and ``..''  are  always  ignored
when  GLOBIGNORE is set and not null.  However, setting GLOBIGNORE to a
non-null value has the effect of enabling the dotglob shell option,  so
all other filenames beginning with a ``.''  will match.  To get the old
behavior of ignoring filenames beginning with a ``.'', make ``.*''  one
of  the  patterns  in  GLOBIGNORE.  The dotglob option is disabled when
GLOBIGNORE is unset.

সুতরাং, একটি ডিরেক্টরিতে সমস্ত ফাইল এবং ফোল্ডার মুছে ফেলার একটি সহজ উপায় :

GLOBIGNORE=.; rm -r *

*শুরু ফাইলের নামের ম্যাচ হবে .সাল থেকে GLOBIGNOREসক্রিয় dotglob, কিন্তু এটা মেলে না হবে .বা .., তাই আপনি যে ভাবে পেরেন্ট ডাইরেক্টরি প্রভাবিত করবে না।

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