ফাইলের তালিকা হিসাবে কীভাবে `find` এর ফলাফলটি পাস করবেন?


11

পরিস্থিতিটি হ'ল, আমার কাছে একটি এমপি 3 প্লেয়ার রয়েছে mpg321যা ফাইলগুলির একটি তালিকা যুক্তি হিসাবে গ্রহণ করে। আমি আমার সংগীতকে "সংগীত" নামের একটি ডিরেক্টরিতে রাখি, যেখানে আরও কয়েকটি ডিরেক্টরি রয়েছে। আমি কেবল তাদের সবগুলি খেলতে চাই, তাই আমি প্রোগ্রামটি চালাচ্ছি

mpg321 $(find /music -iname "*\.mp3")

। সমস্যাটি হ'ল, কিছু ফাইলের নামের মধ্যে তাদের সাদা অংশ রয়েছে এবং প্রোগ্রামটি সেই নামগুলিকে ছোট ছোট ভাগে ভাগ করে দেয় এবং ফাইলগুলি হারিয়ে যাওয়ার বিষয়ে অভিযোগ করে। findউদ্ধৃতিতে ফলাফল মোড়ানো

mpg321 "$(find /music -iname "*\.mp3")"

সহায়তা করে না কারণ সমস্তই একটি বড় "ফাইলের নাম" হয়ে যাবে, যা স্পষ্টতই পাওয়া যায় নি।

আমি কীভাবে এটি করতে পারি? যদি তা গুরুত্বপূর্ণ হয় bashতবে আমি ব্যবহার করছি তবে zshশীঘ্রই স্যুইচ করব ।

উত্তর:


17

এর মত সংমিশ্রণে অনুসন্ধানের -print0বা -printfবিকল্পটি ব্যবহার করার চেষ্টা করুন xargs:

find /music -iname "*\.mp3" -print0 | xargs -0 mpg321

এটি কীভাবে সন্ধানের ম্যানুয়াল পৃষ্ঠা দ্বারা ব্যাখ্যা করা হয় :

-print0

সত্য; স্ট্যান্ডার্ড আউটপুটে সম্পূর্ণ ফাইলের নাম মুদ্রণ করুন, তারপরে নাল অক্ষর (নূতন চরিত্রের পরিবর্তে যা -প্রিন্ট ব্যবহার করে)। এটি ফাইলের নামগুলিতে নিউলাইনগুলি বা অন্যান্য ধরণের শ্বেত স্থানযুক্ত ফাইলগুলির সন্ধানের আউটপুট প্রক্রিয়া করে এমন প্রোগ্রামগুলির দ্বারা সঠিকভাবে ব্যাখ্যা করতে দেয়। এই বিকল্পটি xargs -0 বিকল্পের সাথে মিলে যায়।


সমস্ত সম্পাদনার জন্য দুঃখিত। আমি মনে করি যে-প্রিন্ট 0 xarg -0 প্যাটার্নটি অন্য ধরণের হোয়াইটস্পেসে ব্যর্থ হয়েছে, তবে আমি এর উদাহরণ পাই না।
স্টিভেন ডি

ওহ হ্যাঁ কাজ করে! তবে আমি এখনও ভাবছি কেন mpg321 $(find /music -iname "*\.mp3" -print0)হয় না?
ফোনেহেহে

1
ঠিক আছে, আমি বিশ্বাস করি যে দুটি কারণে কার্যকর হয় না: (1) ফাইলের নামগুলি নাল অক্ষর দ্বারা পৃথক করা হয়েছে, যা এমপিজি 321 মোটেও প্রত্যাশা করে না এবং (২) এক্সার্গস অন্য সাদা স্থান থেকে বেরিয়ে আসার কাজ করছে, না অনুসন্ধান.
স্টিভেন ডি

2
@ ফুনেহে, @ স্টিভেন: এর mpg321সাথে কিছুই করার নেই, এটি শেল যা findপৃথক যুক্তির আউটপুটকে ভেঙে দেয় । এবং -print0 | xargs -0প্রতিটি সম্ভাব্য ফাইলের নাম নিয়ে কাজ করবে।
গিলস 'অশুভ হওয়া বন্ধ করুন'

8
find /music -iname "*\.mp3" -exec mpg123 {} +

জিএনইউ ফাইন্ডের সাহায্যে আপনিও ব্যবহার করতে পারেন -print0এবংxargs -0 , তবে অন্য একটি সরঞ্জাম শিখতে খুব সামান্য অবকাশ রয়েছে। -exec ... {} +কারণ লিনাক্স পরে চেয়ে অর্জিত সিনট্যাক্স সামান্য উল্লেখ পায় -print0, কিন্তু এখন এটি ব্যবহার না করার কোনো কারণ।

Zsh বা ব্যাশ 4 সহ, এটি অনেক সহজ:

mpg123 **/*.[Mm][Pp]3

কেবল zsh এ, আপনি একটি (একটি অংশ) প্যাটার্ন কেস-সংবেদনশীল তৈরি করতে পারেন:

mpg123 (#i)**/*.mp3

এটির জন্য +1, "সন্ধান করুন -প্রিন্ট 0" একটি কুৎসিত হ্যাক।
পি-স্থির

2

আমি মনে করি স্টিভেনের সমাধানটি সর্বোত্তম, তবে আর একটি উপায় হল xargs এর -Iপতাকা ব্যবহার করা , যা আপনাকে একটি স্ট্রিং নির্দিষ্ট করতে দেয় যা কমান্ডের পরে আর্গুমেন্টের সাথে প্রতিস্থাপন করা হবে (কেবলমাত্র কমান্ডের শেষে যুক্তি যুক্ত করার পরিবর্তে)। যুক্তিটি উদ্ধৃত করতে আপনি এটি ব্যবহার করতে পারেন:

find /music -iname "*\.mp3" | xargs -0 -Ifoo mpg321 "foo"

আমি এই উত্তরটি বুঝতে পারি না ... আপনি সন্ধান -0ছাড়াই xargs এর পতাকা ব্যবহার করছেন -print0। এছাড়াও, xargs এর -Iপতাকাটির বেশ কয়েকটি পরিণতি রয়েছে। শুধু সাধারণ ভিন্ন xargsযা এক কমান্ডের মধ্যে stdin থেকে লাইনের সব কম্প্রেস করবে xargs -Iচালানো হবে mpg321সম্ভাব্য শত শত বা হাজার হাজার সময়ের (প্রতিটি ফাইলের জন্য একবার) যা অবশ্যই অভিপ্রায় নয়। এছাড়াও মনে রাখবেন যে xargsঅভ্যন্তরীণভাবে ফু ফু উদ্ধৃত করা অপ্রয়োজনীয় । লক্ষ্য করুন আপনি যদি সমস্ত ফাইলের নাম লাইন লাইনে সংকুচিত করেন এবং এটিকে প্রেরণ করেন তবে xargs -Iসেগুলি খুলবে না।
ছয়

1

এটি সরাসরি সবচেয়ে ভাল -exec ${tgt_process} \{\} +তবে আপনার যদি কোনও কারণেই কোনও ফাইল বা স্ট্রিমের নির্ভরযোগ্যভাবে ডিলিমেটেড তালিকা পেতে প্রয়োজন হয় findতবে আপনি এটি করতে পারেন:

find -exec sh -c 'printf "///%s///\n" "$@"' -- \{\} +

আপনি যেটি থেকে বেরিয়ে আসবেন তা হ'ল দুটি অনন্য স্ট্রিং। প্রতিটি ফাইলনামের মাথায় স্ট্রিং থাকে \n///এবং প্রতিটি ফাইলের লেজের পাশে স্ট্রিং থাকে ///\n। এই দুটি স্ট্রিং findফাইলের নামের মধ্যে যতগুলি অক্ষরই থাকুক না কেন এই অবস্থানগুলি ব্যতীত অন্য কোনও আউটপুটে ঘটে না ।

অতিরিক্ত হিসাবে উপরের ব্যবহারটি বেসলাইন POSIX পোর্টেবল এবং প্রায় কোনও ইউনিক্স সিস্টেমে কাজ করার উপর নির্ভর করা যেতে পারে। এটি নাল বাইট ডিলিমিটার ব্যবহারের ক্ষেত্রে সত্য নয় - এর সুবিধামত থাকা সত্ত্বেও - অন্য কেউ সুপারিশ করেছেন।

তবে, এটি কেবল তখনই প্রয়োজনীয় যদি আপনি যে কোনও কারণে সরাসরি -execআপনার $tgt_processপক্ষে না করতে পারেন , কারণ এটি আপনার লক্ষ্য হওয়া উচিত। একটি জিনিসের জন্য, উপরোক্ত পদ্ধতিটির এখনও বিশ্লেষণ প্রয়োজন। উদাহরণস্বরূপ, আপনি যদি প্রতিটি ফাইলের শেল উদ্ধৃত করতে চান তবে আপনাকে প্রথমে ফাইল-নামের কোনও হার্ড-কোটগুলি রক্ষা পেয়েছে তা নিশ্চিত করতে হবে:

find ... + | sed 's|'\''|&"&"&|g;s|///|'\''|g'

এটি তাদের উপাদানগুলির অক্ষর যাই হউক না কেন ফাইলের নামগুলির একটি সঠিকভাবে শেল-পলায়নের অ্যারে আউটপুট করে। এখন আপনাকে কেবল আশা করতে হবে যে প্রাপ্তির শেষে আপনার অ্যাপ্লিকেশনটি ম্যাঙ্গাল হবে না।


0

এটি করার আরেকটি উপায় হ'ল আপনার ফাইলের নামগুলিতে আসা সমস্ত বিশেষ অক্ষর থেকে বাঁচা। উদাহরণ:

find /music -iname "*\.mp3" | sed 's!\([] \*\$\/&[]\)!\\\1!g' | xargs mpg321

এটি মূলত কার্যকরভাবে পালানো ফাইলের নামটি কার্যকর করার জন্য xargs এ প্রেরণ করবে এবং এতে কোনও সমস্যা হবে না।


1
এটি এখনও ফাইলের নামগুলিতে নতুন লাইনের উপর ব্রেক। এবং আপনি সম্ভবত ন্যায়সঙ্গত sed 's|.|\\&|g'- পসিক্স যেভাবেই প্রস্তাব দেয়।
মাইক্রোজার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.