স্ক্রিপ্টের একটি ভেরিয়েবলের মাধ্যমে ফাইন্ড কমান্ডের পাথ প্যারামিটারে '*' ওয়াইল্ডকার্ড কীভাবে পাস করবেন?


9

আমি findওয়াইল্ডকার্ড দ্বারা সীমাবদ্ধ ফোল্ডারগুলির সেটগুলিতে ফাইলগুলি সন্ধান করতে চাই , তবে যেখানে পথের নামে ফাঁকা স্থান রয়েছে।

কমান্ড লাইন থেকে, এটি সহজ। নিম্নলিখিত উদাহরণগুলি সমস্ত কাজ করে।

find  te*/my\ files/more   -print
find  te*/'my files'/more  -print
find  te*/my' 'files/more  -print

এগুলি উদাহরণস্বরূপ terminal/my files/moreএবং এর মধ্যে ফাইলগুলি সন্ধান করবে tepid/my files/more

যাইহোক, আমার এটি একটি স্ক্রিপ্টের অংশ হতে হবে; আমার যা দরকার তা হ'ল এরকম কিছু:

SEARCH='te*/my\ files/more'
find ${SEARCH} -print

দুর্ভাগ্যক্রমে, আমি যাই করুক না কেন, আমি মনে করি না যে findকোনও স্ক্রিপ্টের মধ্যে একটি কমান্ডের মধ্যে ওয়াইল্ডকার্ড এবং স্পেসগুলি মিশ্রিত করতে সক্ষম হব । উপরের উদাহরণটি নিম্নলিখিত ত্রুটিগুলি প্রদান করে (ব্যাকস্ল্যাশটির অপ্রত্যাশিত দ্বিগুণকরণ নোট করুন):

find: te*/my\\’: No such file or directory
find: files/more’: No such file or directory

উদ্ধৃতি ব্যবহার করার চেষ্টাও ব্যর্থ।

SEARCH="te*/'my files'/more"
find ${SEARCH} -print

এটি উদ্ধৃতিগুলির অর্থ উপেক্ষা করে নিম্নলিখিত ত্রুটিগুলি প্রদান করে:

find: te*/'my’: No such file or directory
find: ‘files'/more’: No such file or directory

এখানে আরও একটি উদাহরণ।

SEARCH='te*/my files/more'
find ${SEARCH} -print

প্রত্যাশিত:

find: te*/my’: No such file or directory
find: files/more’: No such file or directory

আমি চেষ্টা করেছি এমন প্রতিটি প্রকারভেদ একটি ত্রুটি প্রদান করে।

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

SEARCH='te*/my files/more'
SEARCH=${SEARCH// /?}       # Convert every space to a question mark.
find ${SEARCH} -print

এটি সমান:

find te*/my?files/more -print

এটি কেবল সঠিক ফোল্ডারগুলিই নয়, এটিও terse/myxfiles/moreপ্রত্যাখ্যান করে।

আমি যা করার চেষ্টা করছি তা কীভাবে অর্জন করতে পারি? গুগল আমাকে সাহায্য করেনি :(


@ কাসিয়া আমি বাশ ব্যবহার করছি; আপনি অবশ্যই অন্য কিছু ব্যবহার করবেন, যেমনটি আমি এর আগে দেখিনি। কমান্ড ফলাফল SEARCH: command not foundআদেশের সঙ্গে find -printমৃত্যুদন্ড কার্যকর করা হচ্ছে।
ধানের ল্যান্ডাউ

অন্ধকারে একটি শট, তবে উদ্ধৃত করার কী? find "${SEARCH}" -print?
আলা আলী

@ আলাআলি না, এটি কাজ করে না, কারণ উদ্ধৃত করা বাশকে ওয়াইল্ডকার্ড ব্যবহার করা থেকে বিরত করে। এটি নামের সাথে নির্দিষ্টভাবে একটি পথ সন্ধান করবে (আমার উদাহরণে) te*/'my files'/more
ধানের ল্যান্ডউ

উত্তর:


9

ঠিক একই কমান্ডটি স্ক্রিপ্টে কাজ করতে হবে:

#!/usr/bin/env bash
find  te*/my\ files/ -print

আপনার যদি ভেরিয়েবল হিসাবে এটির প্রয়োজন হয় তবে এটি কিছুটা জটিল হয়:

#!/usr/bin/env bash
search='te*/my\ files/'
eval find "$search" -print

সতর্কতা:

এর evalমতো ব্যবহার করা নিরাপদ নয় এবং ফলস্বরূপ এবং সম্ভবত ক্ষতিকারক কোড কার্যকর করতে পারে যদি আপনার ফাইলের নামগুলিতে কিছু নির্দিষ্ট অক্ষর থাকতে পারে। বিশদ জানতে bash FAQ 48 দেখুন ।

যুক্তি হিসাবে পথটি উত্তরণ ভাল:

#!/usr/bin/env bash
find "$@" -name "file*"

আর একটি পদ্ধতি findসম্পূর্ণরূপে এড়ানো এবং বাশের বর্ধিত গ্লোববিং বৈশিষ্ট্য এবং গ্লোবগুলি ব্যবহার করা:

#!/usr/bin/env bash
shopt -s globstar
for file in te*/my\ files/**; do echo "$file"; done

globstarব্যাশ বিকল্পটি ব্যবহার করতে দেয় **যাও recursively মেলে:

globstar
      If set, the pattern ** used in a pathname expansion con
      text will match all files and zero or  more  directories
      and  subdirectories.  If the pattern is followed by a /,
      only directories and subdirectories match.

এটি ডটফাইল (লুকানো ফাইল) সন্ধান এবং অন্তর্ভুক্ত করার মতো 100% কাজ করার জন্য, ব্যবহার করুন

#!/usr/bin/env bash
shopt -s globstar
shopt -s dotglob
for file in te*/my\ files/**; do echo "$file"; done

এমনকি আপনি echoএগুলি সরাসরি লুপ ছাড়াই করতে পারেন :

echo te*/my\ files/**

2
টেরডন যে সহায়ক মন্তব্য করেছে (অন্যের কাছ থেকে সহায়ক মন্তব্যগুলি ভুলে যাবেন না) বলেই আমি এটিকে উত্তর হিসাবে সেট করেছি। আমি স্ক্রিপ্টটিকে বাছাইয়ের চেষ্টা করে স্ক্রিপ্টের পরিবর্তে কমান্ড লাইনে বাশের গ্লোববিং ক্ষমতাটি ব্যবহার করেছি script এটি ভালই কাজ করে.
ধানের ল্যান্ডাউ

2

অ্যারে সম্পর্কে কীভাবে?

$ tree Desktop/ Documents/
Desktop/
└── my folder
    └── more
        └── file
Documents/
└── my folder
    ├── folder
    └── more

5 directories, 1 file
$ SEARCH=(D*/my\ folder)
$ find "${SEARCH[@]}" 
Desktop/my folder
Desktop/my folder/more
Desktop/my folder/more/file
Documents/my folder
Documents/my folder/more
Documents/my folder/folder

(*)ওয়াইল্ডকার্ডের সাথে যা কিছু মেলে তার অ্যারেতে প্রসারিত হয়। এবং "${SEARCH[@]}"অ্যারেতে সমস্ত উপাদানগুলিতে বিস্তৃত হয় ( [@]) প্রতিটি স্বতন্ত্রভাবে উদ্ধৃত হয়।

বিরক্তিকরভাবে, আমি বুঝতে পেরেছি যে এটির পক্ষে নিজেকে সক্ষম করা উচিত। কিছুটা এইরকম:

find . -path 'D*/my folder/more/'

চতুর ধারণা, কিন্তু হায়, এটি কাজ করে না। কেন? কারণ পথটি নিজেই একটি পরিবর্তনশীলতে ধারণ করা হয়; অতএব, INPUTPATH='te*/my files/moreএবং SEARCH=(${INPUTPATH})। আমি এটি করার পদ্ধতিতে আমি কীভাবে পরিবর্তিত হই না কেন, আমি এখনও একটি অ-কার্যকরী ফলাফল দিয়ে শেষ করি। এটা অসম্ভব বলে মনে হচ্ছে!
ধানের ল্যান্ডউ

এটি অবশ্যই সত্য, তবে ওপিটির এটি একটি স্ক্রিপ্টে করা দরকার। ওয়াইল্ডকার্ডগুলির প্রসারণটি উল্লেখযোগ্যভাবে জটিল হয়ে ওঠে এবং এটি কার্যকর হয় না That
টেরডন

@PaddyLandau সালে যে ক্ষেত্রে, কেন তুমি ব্যবহার করতে পারবেন না find'এর -pathফিল্টার? এটি ওয়াইল্ডকার্ড ব্যবহার করে এবং অবশ্যই প্রসারণের প্রয়োজন হয় না।
মুড়ু

@ মুরু এটি আকর্ষণীয়; আমি সম্পর্কে জানতাম না -path। গত 10 মিনিটে যদিও আমি উত্তরটি খুঁজে পেয়েছি: ব্যবহার করুন eval! এটি তুলনায় সহজ বলে মনে হচ্ছে -path
ধানের ল্যান্ডউ

2
@ ইটারডন এবং মুড়ু এবং সকলেই: আপনাকে ধন্যবাদ। আপনারা যা বলেছেন তা আমি শুনেছি এবং আমি বুঝতে পেরেছিলাম যে আমার স্ক্রিপ্টটি একটি কাজ করা উচিত, এবং বাশকে স্ক্রিপ্টে একাধিক ফাইল বা পথ দিয়ে দেওয়া উচিত। আমি আমার স্ক্রিপ্টটি এভাবে পরিবর্তন করেছি। এটি লিনাক্স দর্শনের সাথে ভালভাবে কাজ করে এবং আরও ফিট করে। আবার আপনাকে ধন্যবাদ!
ধানের ল্যান্ডাউ

0

আমি শেষ পর্যন্ত উত্তর খুঁজে পেয়েছি।

সমস্ত স্পেসে একটি ব্যাকস্ল্যাশ যুক্ত করুন:

SEARCH='te*/my files/more'
SEARCH=${SEARCH// /\\ }

এই মুহুর্তে, SEARCHথাকে te*/my\ files/more

তারপরে, ব্যবহার করুন eval

eval find ${SEARCH} -print

এটা যে সহজ! একটি পরিবর্তনশীল থেকে evalযে ব্যাখ্যার বাইপাস করে তা ব্যবহার করে ${SEARCH}



@terdon সতর্কতার জন্য আপনাকে ধন্যবাদ। অঙ্কন বোর্ড ফিরে!
ধানের ল্যান্ডউ

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