একাধিক লাইন আউটপুট বাশ ভেরিয়েবলের ক্যাপচার


580

আমার কাছে একটি স্ক্রিপ্ট 'মাইক্রিপ্ট' রয়েছে যা নিম্নলিখিতগুলির তুলনায় ফলাফল দেয়:

abc
def
ghi

অন্য স্ক্রিপ্টে, আমি কল করি:

declare RESULT=$(./myscript)

এবং $RESULTমান পায়

abc def ghi

ফলাফলগুলি নিউলাইনগুলির সাথে বা '\ n' চরিত্রের সাথে সঞ্চয় করার কোনও উপায় আছে যাতে আমি এটি ' echo -e' দিয়ে আউটপুট করতে পারি ?


1
এটা আমার চমকের. আপনার কাছে cat (বিড়াল। / মাইস্কিপ্ট) নেই? নইলে আমি আশা করতাম যে কমান্ডগুলি
এ.সি.সি., ডিএফ

@ লিটব: হ্যাঁ, আমিও তাই মনে করি; আপনি $ (<./Script) ব্যবহার করতে পারেন যা কোনও আদেশ চালানো এড়ায়।
জোনাথন লেফলার

2
(এনবি: উপরোক্ত দুটি মন্তব্যই প্রশ্নের পুনর্বিবেচনার কথা উল্লেখ করেছে যে আমি একটি স্ক্রিপ্ট 'মাইক্রিপ্ট' পেয়েছি যা নিম্নলিখিতটি ধারণ করে , যা প্রশ্নগুলির দিকে পরিচালিত করেছিল the প্রশ্নের বর্তমান সংশোধন ( আমার একটি স্ক্রিপ্ট পেয়েছে ') ম্যাসক্রিপ্ট 'যা নীচের ফলাফলগুলিকে প্রকাশ করে ) মন্তব্যগুলিকে অতিমাত্রায় পরিণত করে । তবে, এই মন্তব্যটি দুটি মন্তব্য করার অনেক পরে ২০১১-১১ -১১ -১১- এ করা হয়েছে
জোনাথন লেফলার

উত্তর:


1077

প্রকৃতপক্ষে, ফলাফল যা দেখায় ফলাফলগুলি এতে থাকে:

echo "$RESULT"

আপনি যা দেখান তা হ'ল আপনি যা পান:

echo $RESULT

মন্তব্যে উল্লিখিত হিসাবে, পার্থক্যটি হ'ল (1) ভ্যারিয়েবলের ডাবল-কোটড সংস্করণ ( echo "$RESULT") ভেরিয়েবলের মধ্যে যেমনটি প্রদর্শিত হয় ঠিক তেমনভাবে অভ্যন্তরীণ ব্যবধানকে সংরক্ষণ করে - নিউলাইন, ট্যাব, একাধিক ফাঁকা এবং সমস্ত - যেখানে (2) ) অকেজো সংস্করণ ( echo $RESULT) এক বা একাধিক ফাঁকা, ট্যাব এবং নিউলাইনগুলির প্রতিটি ক্রমকে একক স্থানের সাথে প্রতিস্থাপন করে। সুতরাং (1) ইনপুট ভেরিয়েবলের আকৃতি সংরক্ষণ করে, যেখানে (2) একক স্পেস দ্বারা পৃথক পৃথক 'শব্দ' দিয়ে আউটপুটের সম্ভাব্য দীর্ঘ দীর্ঘ একক লাইন তৈরি করে (যেখানে একটি 'শব্দ' শ্বেতস্থান অক্ষরের অনুক্রম; সেখানে অদৃশ্য হওয়া প্রয়োজন) কোনও শব্দের মধ্যে কোনও বর্ণমালা হতে হবে না)।


69
@ ট্রোয়েলস্কন: পার্থক্যটি হ'ল (1) ভেরিয়েবলের ডাবল-কোট করা সংস্করণটি ভেরিয়েবল, নিউলাইনস, ট্যাবগুলি, একাধিক ফাঁকা এবং সমস্ত ক্ষেত্রে যেমন প্রদর্শিত হয় ঠিক তেমন মানটির অভ্যন্তরীণ ব্যবধান সংরক্ষণ করে, যেখানে (2) অব্যক্ত সংস্করণটি প্রতিস্থাপন করে একক স্থানের সাথে এক বা একাধিক ফাঁকা, ট্যাব এবং নতুন লাইনের প্রতিটি ক্রম। সুতরাং (1) ইনপুট ভেরিয়েবলের আকৃতি সংরক্ষণ করে, যেখানে (2) একক স্পেস দ্বারা পৃথক পৃথক 'শব্দ' দিয়ে আউটপুটের সম্ভাব্য দীর্ঘ দীর্ঘ একক লাইন তৈরি করে (যেখানে একটি 'শব্দ' শ্বেতস্থান অক্ষরের অনুক্রম; সেখানে অদৃশ্য হওয়া প্রয়োজন) কোনও শব্দের মধ্যে কোনও বর্ণমালা হতে হবে না)।
জোনাথন লেফলার

23
উত্তরটি বুঝতে সহজতর করার জন্য: উত্তরটি বলে যে প্রতিধ্বনি "ES RESULT" নিউলাইন সংরক্ষণ করে, যখন প্রতিধ্বনি ES RESULT দেয় না।
ইউ শেন

এটি কিছু পরিস্থিতিতে নিউলাইন এবং শীর্ষস্থান সংরক্ষণ করতে ব্যর্থ।
কমাটোস্ট

3
@ কমোটাস্ট: আপনি কি সে সম্পর্কে বিস্তারিত বলতে যাচ্ছেন? ট্রেলিং নিউলাইনগুলি হারিয়ে গেছে; এর কাছাকাছি কোনও সহজ উপায় নেই। নেতৃস্থানীয় ফাঁকা জায়গা - যে পরিস্থিতিতে তারা হারিয়ে গেছে তার সম্পর্কে আমি অবগত নই।
জোনাথন লেফলার


90

এর সাথে আরেকটি ক্ষতি হ'ল কমান্ড প্রতিস্থাপন - $()- নতুন রেখাগুলি অনুসরণ করা স্ট্রিপস। সম্ভবত সর্বদা গুরুত্বপূর্ণ নয়, তবে আপনি যদি সত্যই আউটপুটটি সঠিকভাবে সংরক্ষণ করতে চান তবে আপনাকে অন্য একটি লাইন এবং কিছু উদ্ধৃতি ব্যবহার করতে হবে:

RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"

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


4
আমাকে কিছু সময়ের জন্য একটি ভাঙ্গা শেল দিয়ে কাজ করতে হয়েছিল যা কমান্ড সাবস্টিটিউশন (এটি বিকল্পের প্রক্রিয়া নয় ) থেকে সর্বশেষ নিউলাইনটি সরিয়ে দেয় না এবং এটি প্রায় সমস্ত কিছু ভেঙে ফেলে। উদাহরণস্বরূপ, যদি আপনি এটি করেন তবে আপনি এর আগে একটি নতুন লাইন পেয়েছিলেন এবং ডাবল উদ্ধৃতিতে নামটি লাগানো কোনও উপকারে আসেনি। এটি দ্রুত স্থির করা হয়েছিল। এটি আইসিএল পার্ক পিএনএক্সে 1983-5 সময় ফ্রেমে ফিরে এসেছিল; শেলটি বিল্ট-ইন ভেরিয়েবল হিসাবে নেই। pwd=`pwd`; ls $pwd/$file/$PWD
জোনাথন লেফলার

19

আপনি যদি নির্দিষ্ট লাইনগুলিতে আগ্রহী হন তবে রেজাল্ট-অ্যারে ব্যবহার করুন:

declare RESULT=($(./myscript))  # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"

3
যদি রেখাগুলিতে ফাঁকা স্থান থাকে তবে এটি লাইনগুলির চেয়ে ক্ষেত্রগুলি (স্পেসগুলির মধ্যে থাকা সামগ্রী) গণনা করবে।
লিয়াম

2
আপনি ব্যবহার করেন readarrayএবং প্রক্রিয়া কমান্ড প্রতিকল্পন পরিবর্তে প্রতিকল্পন: readarray -t RESULT < <(./myscript>
চ্যানার

15

@ L0b0 দ্বারা প্রদত্ত উত্তর ছাড়াও আমার সবেমাত্র এমন পরিস্থিতি ছিল যেখানে আমার উভয়কেই স্ক্রিপ্টের মাধ্যমে কোনও চলমান নিউলাইন আউটপুট রাখতে এবং স্ক্রিপ্টের রিটার্ন কোড পরীক্ষা করতে হবে। এবং l0b0 এর উত্তর নিয়ে সমস্যা হ'ল 'ইকো এক্স' রিসেট হচ্ছে $? শূন্যে ফিরে ... সুতরাং আমি এই খুব চালাক সমাধানটি নিয়ে আসতে পেরেছি:

RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"

এটি সুন্দর, আমার আসলে ব্যবহারের ক্ষেত্রে আমি একটি die ()ফাংশন রাখতে চাই যা একটি নির্বিচারে প্রস্থান কোড এবং allyচ্ছিকভাবে একটি বার্তা গ্রহণ করে, এবং আমি usage ()বার্তাটি সরবরাহ করতে অন্য ফাংশনটি ব্যবহার করতে চেয়েছিলাম তবে নতুন লাইনে স্কোয়াশ হতে চলেছে, আশা করি এটি আমাকে দেয় যে চারপাশে কাজ।
ড্রাগন 788

1

এখানে বেশিরভাগ সমাধানের চেষ্টা করার পরে, আমি খুঁজে পেল সবচেয়ে সহজ জিনিসটি ছিল স্পষ্ট - একটি টেম্প ফাইল ব্যবহার করে। আপনার একাধিক লাইন আউটপুট নিয়ে আপনি কী করতে চান তা আমি নিশ্চিত নই, তবে আপনি পঠন ব্যবহার করে লাইন লাইন লেনদেন করতে পারেন। কেবলমাত্র আপনি যা করতে পারবেন না সে সম্পর্কে সহজেই এটি সমস্ত একই ভেরিয়েবলের মধ্যে লেগে থাকে তবে বেশিরভাগ ব্যবহারিক উদ্দেশ্যে এটি মোকাবেলা করা সহজ way

./myscript.sh > /tmp/foo
while read line ; do 
    echo 'whatever you want to do with $line'
done < /tmp/foo

এটি অনুরোধকৃত ক্রিয়াটি করতে দ্রুত হ্যাক করুন:

result=""
./myscript.sh > /tmp/foo
while read line ; do
  result="$result$line\n"
done < /tmp/foo
echo -e $result

নোট করুন এটি একটি অতিরিক্ত লাইন যুক্ত করে। আপনি যদি এটিতে কাজ করেন তবে আপনি তার চারপাশে কোড করতে পারেন, আমি ঠিক খুব অলস।


সম্পাদনা: যদিও এই কেসটি পুরোপুরি ভালভাবে কাজ করে, এই বিষয়টি পড়তে থাকা লোকদের সচেতন হওয়া উচিত যে আপনি যখন সময় লুপের মধ্যে সহজেই আপনার স্টিডিনকে স্কোয়াশ করতে পারেন, সুতরাং আপনাকে এমন একটি স্ক্রিপ্ট দেবে যা একটি লাইন, ক্লিয়ার স্টিডিন এবং প্রস্থান করবে। আমার কি মনে হয় এসএস-এর মতো করবে? আমি সম্প্রতি এটি দেখেছি, অন্যান্য কোড উদাহরণগুলি এখানে: /unix/24260/reading-lines-from-a-file-with-bash-for-vs- moment

আরো এক বার! এবার আলাদা ফাইলহ্যান্ডেলের সাহায্যে (স্টিডিন, স্টাডআউট, স্ট্ডার 0-2 হয়, তাই আমরা ব্যাশে আরও 3 বা তার বেশি ব্যবহার করতে পারি)।

result=""
./test>/tmp/foo
while read line  <&3; do
    result="$result$line\n"
done 3</tmp/foo
echo -e $result

আপনি এমকেটেম্পও ব্যবহার করতে পারেন তবে এটি কেবলমাত্র একটি দ্রুত কোড উদাহরণ। এমকেটেম্পের ব্যবহার দেখে মনে হচ্ছে:

filenamevar=`mktemp /tmp/tempXXXXXX`
./test > $filenamevar

তারপরে $ ফাইলের নাম ব্যবহার করুন আপনার মতো কোনও ফাইলের আসল নাম। সম্ভবত এখানে ব্যাখ্যা করার দরকার নেই তবে কেউ মন্তব্য করে অভিযোগ করেছেন।


আমি অন্যান্য সমাধানও চেষ্টা করেছিলাম, আপনার প্রথম পরামর্শের সাথে অবশেষে আমার স্ক্রিপ্টটি কাজ করতে পেরেছি
Kar.ma

1
Downvote এই বেজায় জটিল, এবং একাধিক সাধারণ এড়াতে ব্যর্থ bashফাঁদ
ট্রিপলি

ইয়া অন্য কেউ আমাকে অদ্ভুত স্ট্ডিন ফাইলহ্যান্ডেলের সমস্যা সম্পর্কে বলেছিল এবং আমি "বাহ" এর মতো ছিলাম। লেমমে সত্যিই দ্রুত কিছু যুক্ত করুন।
ব্যবহারকারী 1279741

বাশে, আপনি ফাইল বর্ণনাকারী 3 থেকে পড়তে readকমান্ড এক্সটেনশনটি ব্যবহার করতে পারেন-u 3
জোনাথন লেফলার

কেনো না ... কর ... সম্পন্ন <<(। Myscript.sh)
jtgd

0

এটি সম্পর্কে কীভাবে, এটি প্রতিটি লাইনটি একটি ভেরিয়েবলের কাছে পড়বে এবং এটি পরে ব্যবহার করা যেতে পারে! বলুন মাইক্রিপ্ট আউটপুট মাইক্রিপ্ট_আউটপুট নামে একটি ফাইলে পুনঃনির্দেশিত say

awk '{while ( (getline var < "myscript_output") >0){print var;} close ("myscript_output");}'

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