Zsh এ স্পেস সহ উপাদানগুলি তালিকাভুক্ত করুন


10

আমি এই সময়ে 2 ঘন্টা ধরে zsh স্ক্রিপ্টিং অধ্যয়ন করছি এবং আমি একটি প্রাচীর আঘাত করেছি। আমি ফাইলগুলির একটি তালিকা দিয়ে যেতে চাই যেগুলির মধ্যে স্পেস থাকতে পারে। আমি নিচের উদাহরণের তুলনায় সম্পূর্ণ ভিন্ন পদ্ধতির জন্য উন্মুক্ত আছি যতক্ষণ তারা zsh হয় যেহেতু zsh যা আমি পড়াশোনা করছি, আমি যে কাজটি স্ক্রিপ্ট করার চেষ্টা করছি তা নয়।

files=(`ls`)
for f in $files; do
    print $f
done

আমি স্পষ্টতই পুনরুক্তি করছি না ls, আমি $fলুপটির প্রতিটি পুনরাবৃত্তি পুরো ফাইলের নামটি ধারণ করতে চাই ।

উত্তর:


12

প্রথমত, আমি ধরে নিই যে ব্যবহারটি lsকেবল একটি উদাহরণ। আপনি lsকোনও শেলের আউটপুট বিশ্লেষণ করতে পারবেন না , কারণ এটি অস্পষ্ট। পড়ুন কেন আপনার ls (1) এর আউটপুট বিশ্লেষণ করবেন না যদি এটি আপনার কাছে খবর news যে কোনও শেলের মধ্যে ফাইলের একটি তালিকা পেতে ওয়াইল্ডকার্ডগুলি ব্যবহার করুন, যেমন files=(*)

Zsh তে, অন্যান্য শেলের মতো, কমান্ড প্রতিস্থাপনের ফলাফলটি হোয়াইটস্পেস অক্ষরগুলিতে শব্দগুলিতে বিভক্ত হয় (আরও স্পষ্টভাবে, এর মান অনুসারে IFS)। (অন্যান্য শাঁসের বিপরীতে, কমান্ড প্রতিস্থাপনের ফলাফলটি zsh এ গ্লোব্বিংয়ের সাপেক্ষে নয়)) সুতরাং যদি lsকমান্ডের আউটপুট হয়

hello world
wibble

তারপর files=($(ls))সেট করে filesঅ্যারে 3 উপাদানগুলি থাকবে না: hello, worldএবং wibble

যদি কমান্ড প্রতিস্থাপনটি ডাবল কোটে থাকে, তবে কোনও বিভাজন করা হবে না। আপনি প্যারামিটার বিস্তৃত পতাকাগুলির সাথে কাস্টম বিভাজন করতে পারেন । @বিভক্তির ফলাফলটি একটি অ্যারে হতে হবে তা চিহ্নিত করতে পতাকাটি ব্যবহার করুন (অদ্ভুতভাবে, আপনাকে ডাবল উদ্ধৃতিতে সম্প্রসারণটি রাখা দরকার "${(@)…}", যদিও ডাবল-কোটড স্ট্রিংটি একাধিক শব্দে প্রসারিত হবে)। বিভাজনের জন্য, sপতাকাটি ব্যবহার করুন , যেমন "${(@s:,:)…}"কমাতে বিভক্ত করতে; fপতাকা শুধুমাত্র নতুন লাইন এ splits।

files=("${(@f)$(ls)}")

নোট যে সাধারণভাবে একটি অ্যারের পুনরুক্তি উপর সঠিক ভাবে for f in $files[@], যেমন $filesখালি উপাদান (এখানে, এটা ব্যাপার কারণ উপাদানের খালি হবে না না) বন্ধ রেখাচিত্রমালা।

print $f$fযদি এটি শুরু হয় -এবং ব্যাকস্ল্যাশগুলি প্রসারিত করে তবে একটি স্যুইচ হিসাবে ব্যাখ্যা করে $f। ব্যবহার করুন print -r -- $f, বা print -rn -- $fআপনি স্ট্রিং পরে একটি নতুন লাইন যোগ করতে না চান।


ধন্যবাদ. হ্যাঁ, ls কেবল একটি উদাহরণ ছিল। এই মুহুর্তে কোনও নির্দিষ্ট লক্ষ্য ছিল না, আমি কেবল জানতে চাইছি যে কোনও আদেশ থেকে তালিকার উপাদানগুলি কীভাবে উদ্ধৃত করতে হবে বা এড়িয়ে যেতে হবে যার মধ্যে সাদা স্থান সহ পৃথক ফলাফল হতে পারে might
ফেলিক্স

আমি একটি বিভ্রান্তিকর বিষয় খুঁজে পেয়েছি তা হল আপনার ফাইলে = ("$ {(@ f) $ (ls)}")) এর বহিরাগত প্রকাশটি @f এর সাথে কেন প্রয়োজনীয়? এবং কেবল চারপাশে খেলে (চ) যতক্ষণ না বাইরে প্রদর্শিত হবে ঠিক ততক্ষণ কাজ করবে।
কুবজ

@ কুবজ ১. বাইরেরটি (…)প্রয়োজনীয় যাতে এটি filesএকটি অ্যারে এবং স্ট্রিং নয় (যা কমান্ড থেকে রেখার সংমিশ্রণ ধারণ করে, বিভাজকটি পূর্বে পূর্বে তৈরি করে (f))। 2. foo=$'one\n\nthree', contrast মুদ্রণ -rl $ {(চ) ফু} `এবং সহ print "${(@f)foo}"। খালি রেখাগুলি ধরে রাখতে ডাবল উদ্ধৃতি প্রয়োজন, যা আপনি পাবেন না lsতবে অন্যান্য কমান্ডের সাহায্যে ঘটতে পারে।
গিলস'স'-দুষ্ট হওয়া বন্ধ করুন '

অনেক প্রশংসিত. এই উন্মাদনার কোনও ছড়া বা কারণ আছে কি? এমনকি সেখানে, বিভ্রান্তিকর কারণ হ'ল কেন মধ্যবর্তী মানটি আমার সংলগ্ন স্ট্রিং যদি বাইরের () কেবল পৃথক শব্দের উপর আবার স্ট্রিংকে আবার বিভক্ত করে না। উদাহরণস্বরূপ এটি রুবি বা পিএইচপিতে স্ট্রিং অন্তরঙ্গনের মতো দেখায়।
কুবজ

@ কোবজ খালি শব্দের বিশেষ চিকিত্সার কারণ zsh এর দীর্ঘ-ভুলে যাওয়া পুরানো সংস্করণগুলির সাথে historicalতিহাসিক সামঞ্জস্য। স্বয়ংক্রিয়ভাবে বিভক্ত না হওয়ার কারণ হ'ল এটি আশ্চর্যজনক এবং প্রায়শই কাঙ্ক্ষিত আচরণ নয়। স্বয়ংক্রিয়ভাবে বিভক্ত হওয়া বোর্ন শেলের এমন একটি আচরণ যা zsh অনুকরণ করে না যতক্ষণ না আপনি এটি না বলেন।
গিলস'স'-দুষ্ট হওয়া বন্ধ করুন '

2

Zsh এ আপনি শেলের সম্প্রসারণ ব্যবহার করতে পারেন যা ডিফল্টরূপে শব্দ বিভাজন করে না। চেষ্টা

for f in /path/to/files/*; do
    print ${f}
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.