উত্তর:
ব্যাশ আপনি এটা সক্ষম করে কি করতে পারেন extglob
এই মত, বিকল্প (প্রতিস্থাপন ls
সঙ্গে cp
এবং টার্গেট ডিরেক্টরির যোগ করুন, অবশ্যই)
~/foobar> shopt extglob
extglob off
~/foobar> ls
abar afoo bbar bfoo
~/foobar> ls !(b*)
-bash: !: event not found
~/foobar> shopt -s extglob # Enables extglob
~/foobar> ls !(b*)
abar afoo
~/foobar> ls !(a*)
bbar bfoo
~/foobar> ls !(*foo)
abar bbar
আপনি পরে এক্সটগ্লোব অক্ষম করতে পারেন
shopt -u extglob
f
বাদ দিয়ে foo
?
extglob
শেল বিকল্পটি কমান্ড লাইনে আরো শক্তিশালী প্যাটার্ন ম্যাচিং দেয়।
আপনি এটি চালু করুন shopt -s extglob
এবং এটি দিয়ে বন্ধ করুন shopt -u extglob
।
আপনার উদাহরণে, আপনি প্রাথমিকভাবে এটি করতে হবে:
$ shopt -s extglob
$ cp !(*Music*) /target_directory
পূর্ণ প্রাপ্তিসাধ্য EXT শেষ হয়েছে উল্লিখিত glob Bing অপারেটার (থেকে উদ্ধৃতাংশ হয় man bash
):
এক্সটগ্লোব শেল বিকল্পটি শপ্ট বিল্টিন ব্যবহার করে সক্ষম করা থাকলে, বেশ কয়েকটি বর্ধিত প্যাটার্ন মেলানো অপারেটরগুলি স্বীকৃত। একটি প্যাটার্ন-তালিকা হ'ল একটি দ্বারা বিচ্ছিন্ন এক বা একাধিক নিদর্শনগুলির একটি তালিকা। নিম্নলিখিত এক বা একাধিক উপ-নিদর্শন ব্যবহার করে যৌগিক নিদর্শনগুলি গঠিত হতে পারে:
- ? (প্যাটার্ন-তালিকা)
প্রদত্ত নিদর্শনগুলির শূন্য বা একটি ঘটনার সাথে মেলে- * (প্যাটার্ন-তালিকা)
প্রদত্ত নিদর্শনগুলির শূন্য বা তার বেশি সংখ্যার সাথে মেলে- + (প্যাটার্ন-তালিকা)
প্রদত্ত নিদর্শনগুলির এক বা একাধিক ঘটনার সাথে মেলে- @ (প্যাটার্ন-তালিকা)
প্রদত্ত নিদর্শনগুলির মধ্যে একটির সাথে মেলে- ! (প্যাটার্ন-তালিকা)
প্রদত্ত নিদর্শনগুলির ব্যতীত অন্য কোনও কিছুর সাথে মেলে
সুতরাং, উদাহরণস্বরূপ, আপনি যদি বর্তমান ডিরেক্টরিতে থাকা ফাইল .c
বা .h
ফাইল নয় এমন সমস্ত ফাইল তালিকাভুক্ত করতে চান তবে আপনি তা করতে পারেন:
$ ls -d !(*@(.c|.h))
অবশ্যই, সাধারণ শেল গ্লোবিং কাজ করে, তাই শেষ উদাহরণটিও এটি হিসাবে লেখা যেতে পারে:
$ ls -d !(*.[ch])
.c
বা .h
ফাইলগুলির মধ্যে একটি ডিরেক্টরি হয় সেটির জন্য ।
D
, তবে ডিরেক্টরিতে থাকা সাব-ডাইরেক্টরিগুলির সামগ্রী নয় D
।
ব্যাশে নয় (যা আমি জানি) তবে:
cp `ls | grep -v Music` /target_directory
আমি জানি এটি ঠিক আপনি যা খুঁজছিলেন তা নয়, তবে এটি আপনার উদাহরণ সমাধান করবে।
আপনি যদি এক্সিকিউটিভ কমান্ডটি ব্যবহারের স্মৃতিচারণা এড়াতে চান তবে আমি বিশ্বাস করি যে আপনি xargs দিয়ে আরও ভাল করতে পারবেন। আমি মনে করি নিম্নলিখিতগুলির আরও কার্যকর বিকল্প
find foo -type f ! -name '*Music*' -exec cp {} bar \; # new proc for each exec
find . -maxdepth 1 -name '*Music*' -prune -o -print0 | xargs -0 -i cp {} dest/
ব্যাশ সালে বিকল্প shopt -s extglob
নেই GLOBIGNORE
পরিবর্তনশীল । এটি আসলে ভাল নয়, তবে মনে রাখা এটি আমার পক্ষে সহজ।
একটি উদাহরণ যা মূল পোস্টারটি চেয়েছিল তা হতে পারে:
GLOBIGNORE="*techno*"; cp *Music* /only_good_music/
হয়ে গেলে সোর্স ডিরেক্টরিতে unset GLOBIGNORE
সক্ষম হতে rm *techno*
।
আপনি খুব সহজ for
লুপ ব্যবহার করতে পারেন :
for f in `find . -not -name "*Music*"`
do
cp $f /target/dir
done
-maxdepth 1
অ recursive জন্য ব্যবহার করবেন?
find
ব্যাকটিক্স ব্যবহার করা অপ্রীতিকর উপায়ে ভেঙে যায় যদি এটি কোনও অকার্যকর ফাইলের নাম খুঁজে পায়।
আমার ব্যক্তিগত পছন্দটি হ'ল গ্রেপ এবং সময় কমান্ডটি ব্যবহার করা। এটি একটিকে শক্তিশালী এখনও পঠনযোগ্য স্ক্রিপ্টগুলি লেখার অনুমতি দেয় যাতে আপনি যা চান ঠিক তেমনই শেষ করেন doing এছাড়াও ইকো কমান্ড ব্যবহার করে আপনি প্রকৃত ক্রিয়াকলাপ চালানোর আগে একটি শুকনো রান সঞ্চালন করতে পারেন। উদাহরণ স্বরূপ:
ls | grep -v "Music" | while read filename
do
echo $filename
done
আপনার অনুলিপি করা ফাইলগুলি মুদ্রণ করবে। তালিকাটি সঠিক হলে পরবর্তী পদক্ষেপটি হ'ল ইকো কমান্ডটি অনুলিপি করে নিম্নরূপ:
ls | grep -v "Music" | while read filename
do
cp "$filename" /target_directory
done
bash
আপনি ব্যবহার করতে পারেন while IFS='' read -r filename
, কিন্তু তারপর নতুন লাইন এখনও কোন সমস্যা আছে। সাধারণভাবে ls
ফাইলগুলি গণনার জন্য ব্যবহার না করা ভাল ; মত সরঞ্জাম find
অনেক ভাল উপযুক্ত।
for file in *; do case ${file} in (*Music*) ;; (*) cp "${file}" /target_directory ; echo ;; esac; done
একটি কৌতুক আমি এখানে এখনো দেখা যায় না যে ব্যবহার করে না extglob
, find
অথবা grep
সেট হিসাবে দুই ফাইল তালিকা এবং চিকিত্সা হয় "পরিবর্তন" তাদের ব্যবহার comm
:
comm -23 <(ls) <(ls *Music*)
comm
এটি বেশি পছন্দসই diff
কারণ এটিতে অতিরিক্ত ক্রাফ্ট নেই।
এই আয় সেট 1 সব উপাদান, ls
যে হয় না সেট 2 এছাড়াও ls *Music*
। এটি সঠিকভাবে কাজ করার জন্য উভয় সেটকে বাছাই করা দরকার। কোনও সমস্যা ls
এবং গ্লোব সম্প্রসারণের জন্য কোনও সমস্যা নেই তবে আপনি যদি এর মতো কিছু ব্যবহার করেন find
তবে অবশ্যই অনুরোধ করবেন sort
।
comm -23 <(find . | sort) <(find . | grep -i '.jpg' | sort)
সম্ভাব্য কার্যকর।
comm -23 <(ls) exclude_these.list
এর জন্য একটি সমাধান খুঁজে পাওয়া যাবে।
$ mkdir foo bar
$ touch foo/a.txt foo/Music.txt
$ find foo -type f ! -name '*Music*' -exec cp {} bar \;
$ ls bar
a.txt
ফাইন্ডে বেশ কয়েকটি অপশন রয়েছে, আপনি কী অন্তর্ভুক্ত করবেন এবং বাদ দেবেন সে সম্পর্কে আপনি বেশ সুনির্দিষ্টভাবে জানতে পারেন।
সম্পাদনা করুন: মন্তব্যগুলিতে অ্যাডাম উল্লেখ করেছেন যে এটি পুনরাবৃত্ত। অপশনগুলি মাইন্ডপথ এবং ম্যাক্সডেপথ এটি নিয়ন্ত্রণে কার্যকর হতে পারে find
find -maxdepth 1 -not -name '*Music*'
/ টার্গেট_ডাইরেক্টরি
নীচের কাজগুলি *.txt
একটি সংখ্যা দিয়ে শুরু হওয়া ফাইলগুলি বাদ দিয়ে বর্তমান দিরের সমস্ত ফাইলের তালিকা করে ।
এই কাজ করে bash
, dash
, zsh
এবং সমস্ত অন্যান্য POSIX সামঞ্জস্যপূর্ণ শাঁস।
for FILE in /some/dir/*.txt; do # for each *.txt file
case "${FILE##*/}" in # if file basename...
[0-9]*) continue ;; # starts with digit: skip
esac
## otherwise, do stuff with $FILE here
done
লাইন এক প্যাটার্ন /some/dir/*.txt
কারণ হবে for
সব ফাইল পুনরুক্তি উপর লুপ /some/dir
যার নাম দিয়ে শেষ .txt
।
লাইন দুটিতে কেস স্টেটমেন্টটি অনাকাঙ্ক্ষিত ফাইলগুলিকে আগাছা করার জন্য ব্যবহৃত হয়। - ${FILE##*/}
এক্সপ্রেশনটি ফাইলের নাম (এখানে /some/dir/
) থেকে যে কোনও নেতৃস্থানীয় দির নাম উপাদানকে সরিয়ে দেয় যাতে প্যাটারগুলি কেবল ফাইলের বেসনামের সাথে মেলে। (যদি আপনি প্রত্যয়গুলির উপর ভিত্তি করে কেবল ফাইলের নামগুলি ঝাঁকিয়ে থাকেন তবে আপনি এটির $FILE
পরিবর্তে এটি সংক্ষিপ্ত করতে পারেন ))
তিন লাইনে, case
প্যাটার্নের সাথে মেলে সমস্ত ফাইল [0-9]*
) লাইন ছেড়ে দেওয়া হবে ( continue
বিবৃতিটি লুপটির পরবর্তী পুনরাবৃত্তিতে for
পৌঁছায়)। - আপনি চাইলে এখানে আরও কিছু আকর্ষণীয় কাজ করতে পারেন, যেমন চিঠি দিয়ে শুরু না হওয়া সমস্ত ফাইলগুলি এড়িয়ে যাওয়া (a – z) [!a-z]*
, অথবা আপনি বিভিন্ন ধরণের ফাইলের নাম এড়াতে একাধিক নিদর্শন ব্যবহার করতে পারেন যেমন [0-9]*|*.bak
উভয় .bak
ফাইল এড়িয়ে যেতে , এবং ফাইলগুলি যা কোনও সংখ্যার সাথে শুরু হয় না।
*.txt
পরিবর্তে এর সাথে মেলে *
)। এখনই স্থির।
এটি ঠিক 'সংগীত' বাদ দিয়ে এটি করবে
cp -a ^'Music' /target
এটি এবং এটি সঙ্গীত? * বা *? সংগীতের মতো জিনিস বাদ দেওয়ার জন্য
cp -a ^\*?'complete' /target
cp -a ^'complete'?\* /target
cp
MacOS এ ম্যানুয়াল পৃষ্ঠায় একটি -a
বিকল্প রয়েছে তবে এটি সম্পূর্ণ আলাদা কিছু করে। কোন প্ল্যাটফর্ম এটিকে সমর্থন করে?
ls /dir/*/!(base*)