আর্গুমেন্ট হিসাবে পরের কমান্ডের আউটপুট পাস করুন to


117

আমি একটি কমান্ড করেছি যা স্টাডআউট ( command1 -p=aaa -v=bbb -i=4) এ ডেটা আউটপুট করে । আউটপুট লাইনে নিম্নলিখিত মান থাকতে পারে:

rate (10%) - name: value - 10Kbps

সেই 'রেট' সংরক্ষণ করার জন্য আমি সেই আউটপুট গ্রেপ করতে চাই (আমার ধারণা পাইপটি এখানে কার্যকর হবে)। এবং পরিশেষে, আমি এই হারটি দ্বিতীয় কমান্ডের প্যারামিটারের মান হতে চাই (আসুন আমরা বলি command2 -t=${rate})

এটি আমার পক্ষে কৃপণ বলে মনে হচ্ছে; আমি কীভাবে পাইপ, গ্রেপ, সেড ইত্যাদি ব্যবহার করতে পারি তা আরও ভালভাবে জানতে চাই।

আমি এর মতো প্রচুর সংমিশ্রণ চেষ্টা করেছি কিন্তু আমি এগুলিতে বিভ্রান্ত হচ্ছি:

$ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate}

উত্তর:


142

আপনি দুটি খুব ভিন্ন ধরণের ইনপুট গুলিয়ে ফেলছেন।

  1. স্ট্যান্ডার্ড ইনপুট ( stdin)
  2. কমান্ড লাইন আর্গুমেন্ট

এগুলি পৃথক, এবং বিভিন্ন উদ্দেশ্যে কার্যকর। কিছু কমান্ড উভয় উপায়ে ইনপুট নিতে পারে, তবে তারা সাধারণত এগুলি আলাদাভাবে ব্যবহার করে। উদাহরণ হিসাবে উদাহরণস্বরূপ নিন wc:

  1. এর মাধ্যমে পাসিং ইনপুট stdin:

    ls | wc -l
    

    এর আউটপুটে লাইনগুলি গণনা করবে ls

  2. কমান্ড লাইন আর্গুমেন্ট দ্বারা ইনপুট পাস করা:

    wc -l $(ls)
    

    এটি মুদ্রিত ফাইলগুলির তালিকায় লাইন গণনা করবেls

সম্পূর্ণ ভিন্ন জিনিস।

আপনার প্রশ্নের উত্তর দেওয়ার জন্য, মনে হচ্ছে আপনি প্রথম কমান্ডের আউটপুট থেকে হারটি ক্যাপচার করতে চান এবং তারপরে দ্বিতীয় কমান্ডের জন্য কমান্ড লাইন আর্গুমেন্ট হিসাবে হারটি ব্যবহার করতে চান। এটি করার একটি উপায় এখানে:

rate=$(command1 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p')
command2 -t "rate was $rate"

এর ব্যাখ্যা sed:

  • s/pattern/replacement/কমান্ড কিছু প্যাটার্ন প্রতিস্থাপন করতে হয়
  • প্যাটার্নটির অর্থ: লাইনটি অবশ্যই "হার" ( ^rate) দিয়ে শুরু করতে হবে দুটি অক্ষর ( ..) এর পরে, 0 বা তার বেশি সংখ্যার পরে, এর পরে a %, বাকী পাঠ্য অনুসরণ করবে ( .*)
  • \1প্রতিস্থাপনের অর্থ হ'ল প্রথম অভিব্যক্তিটির কন্টেন্টের মধ্যে থাকা \(...\), সুতরাং %সাইন এর আগে অঙ্কগুলি
  • -nপতাকা sedকমান্ড ডিফল্টরূপে লাইন মুদ্রণ করতে মানে। pশেষে s///কমান্ড লাইন প্রিন্ট করতে যদি তালিকায় সঠিক বানানটি ছিল মানে। সংক্ষেপে, কমান্ডটি কোনও মিল থাকলে কেবল কিছু মুদ্রণ করবে।

12

আমি এটি ব্যবহার করার ঝোঁক:

command1 | xargs -I{} command2 {}

command1প্রতিস্থাপন (ধনুর্বন্ধনী) ব্যবহার করে xargs মাধ্যমে আউটপুট পাস করুন command2। কমান্ড 1 যদি findনিশ্চিত হয়ে থাকে যে নাল টার্মিনেটেড স্ট্রিংগুলি ব্যবহার করার জন্য -print0যুক্ত -0করা হবে এবং প্রতিটি জিনিস খুঁজে পাওয়া জন্য কল করবে ।xargsxargscommand2

আপনার ক্ষেত্রে (এবং @ জ্যানোস থেকে সেড লাইন নেওয়া):

command1 -p=aaa -v=bbb -i=4 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p' | xargs -I{} command2 -t="rate was {}"

এটি জিনিসগুলি সুন্দর এবং পাইপ রাখে, এ কারণেই আমি এটি পছন্দ করি।
মতিন উলহাক

4

এর আউটপুট অনুকরণ করতে command1আমি এই প্রতিধ্বনি বিবরণটি ব্যবহার করছি:

$ echo -e "Foo\nrate (10%) - name: value - 10Kbps\nBar"
$ alias command1='echo -e "Blah\nrate (10%) - name: value - 10Kbps\nBlag"'

একটি দ্রুত পরীক্ষা:

$ command1
Blah
rate (10%) - name: value - 10Kbps
Blag

সব ভাল, তাই এটি পার্স আউট যাক:

$ command1 | grep 'rate'
rate (10%) - name: value - 10Kbps

সুতরাং আমরা যে রেখার বাইরে যেতে চাই তা পাই command1, এটি এর মধ্যে দিয়ে দেওয়া যাক command2:

$ alias command2='echo'
$ command2 -t="rate was "$(command1 | grep 'rate')
-t=rate was rate (10%) - name: value - 10Kbps

আমি "rate was "$(command1 | grep 'rate')স্বয়ংক্রিয়ভাবে সম্মিলিত আশা করছি । যদি হোয়াইটস্পেসের কারণে এটি কাজ না করে তবে আপনার পরিবর্তে ইনপুটটি পাস করতে সক্ষম হওয়া উচিত:

$ alias command2='echo'
$ command2 -t=$(echo '"rate was ' $(command1 | grep 'rate') '"')
-t="rate was rate (10%) - name: value - 10Kbps "


2

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

command1 -p=aaa -v=bbb -i=4 | grep -o -P '[0-9]+(?=%)'

আর একটি সম্ভাবনা রয়েছে সেড ব্যবহার করা। সেডে একটি লাইনের একটি অংশ বের করতে, sকমান্ডটি ব্যবহার করুন , একটি রেইগেক্স সহ পুরো লাইনের সাথে মেলে (শুরু করে ^এবং শেষ হবে $), অংশটি একটি গ্রুপে ধরে রাখার জন্য \(…\)। গোষ্ঠীটির গোষ্ঠীগুলির সামগ্রীতে সম্পূর্ণ লাইনটি প্রতিস্থাপন করুন। সাধারণভাবে, -nডিফল্ট মুদ্রণ বন্ধ করার বিকল্পটি পাস করুন এবং pমুদ্রকগুলিকে মুদ্রণের জন্য প্রিন্ট করুন যেখানে সেখানে এক্সট্র্যাক্ট করার মতো কিছু রয়েছে (এখানে একটি একক লাইন রয়েছে যাতে এটি বিবেচনা করে না)। দেখুন একটি মানানসই প্যাটার্ন পর একটি লাইন একমাত্র অংশ ফিরুন এবং একটি Regex পার্শ্ববর্তী অক্ষর মুদ্রণ ছাড়া সঙ্গে 'sed' মিলেছে নিষ্কাশন হচ্ছে আরও কিন্তু ঠাট জন্য।

command1 -p=aaa -v=bbb -i=4 | sed 's/^.*rate(\([0-9]*\)%).*$/\1/'

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

command1 -p=aaa -v=bbb -i=4 | awk '{gsub(/[^0-9]+/, "", $2); print $2}'

পরবর্তী পদক্ষেপ, এখন আপনি যে হারটি বের করেছেন, তা হ'ল যুক্তি হিসাবে এটি পাস করা command2এটির জন্য সরঞ্জামটি হ'ল একটি কমান্ড সাসব্যাটিউশন । আপনি যদি কমান্ডটি ভিতরে রাখেন $(…)(ডলার-প্রথম বন্ধনী), এর আউটপুট কমান্ড লাইনে প্রতিস্থাপিত হবে। কমান্ডের আউটপুট প্রতিটি হোয়াইটস্পেস ব্লকে পৃথক শব্দে বিভক্ত হয় এবং প্রতিটি শব্দ একটি ওয়াইল্ডকার্ড প্যাটার্ন হিসাবে বিবেচিত হয়; যদি না আপনি এই ঘটতে করতে চান, কমান্ড প্রতিকল্পন প্রায় ডবল কোট করা: "$(…)"। ডাবল উদ্ধৃতি সহ, কমান্ডের আউটপুটটি সরাসরি একক প্যারামিটার হিসাবে ব্যবহৃত হয় (একমাত্র রূপান্তরটি আউটপুটটির শেষে থাকা নিউলাইনগুলি সরিয়ে ফেলা হয়)।

command2 -t "$(command1 -p=aaa -v=bbb -i=4 |
               sed 's/^.*rate(\([0-9]*\)%).*$/\1/')"

0

আপনি ব্যবহার করতে পারেন grepএবং এটি পিসিআরই - পার্ল সামঞ্জস্যপূর্ণ নিয়মিত এক্সপ্রেশন। এটি আপনাকে গ্রেপিংয়ের সময় আপনার ফলাফলের মধ্যে "রেট" স্ট্রিংকে অন্তর্ভুক্ত না করে রেটের মানের সাথে মিল রাখতে একটি চেহারাদ্বীপ ব্যবহার করতে দেয়।

উদাহরণ

$ echo "rate (10%) - name: value - 10Kbps" | grep -oP '(?<=^rate \()\d+'
10

বিস্তারিত

উপরোক্ত grepকাজগুলি নিম্নরূপ:

  • -oকেবলমাত্র আমরা \d+যা খুঁজছি তা ফিরে আসবে , যা পেরেনগুলির মধ্যে অঙ্কগুলি।
  • -P গ্রেপের পিসিআরই বৈশিষ্ট্য সক্ষম করে
  • (?<=^rate \() কেবল "রেট (") দিয়ে শুরু হওয়া স্ট্রিংগুলি ফিরিয়ে আনবে

command2

"রেট" এর মান ধরার জন্য আপনি command1এভাবে চালাতে পারেন:

$ rate=$(command 1 | grep -oP '(?<=^rate \()\d+'

তারপরে আপনার ২ য় কমান্ডের জন্য আপনি কেবল সেই পরিবর্তনশীলটি ব্যবহার করবেন।

$ command2 -t=${rate}

আপনি অভিনবতা পেতে এবং এটি সমস্ত এক লাইন করতে পারে:

$ command2 -t=$(command1 | grep -oP '(?<=^rate \()\d+')

এটি $(..)এক্সিকিউশন ব্লকের ভিতরে কমান্ড 1 চালাবে , ফলাফল নেবে এবং কমান্ড 2 এর স্যুইচে অন্তর্ভুক্ত করবে -t=..


0

আমি আউটপুটটিকে অন্য কমান্ডের আর্গুমেন্ট হিসাবে রাখার জন্য সাধারণত "কমান্ড" ব্যবহার করি। উদাহরণস্বরূপ, ফ্রিবিএসডি-তে প্রক্রিয়া ফু দ্বারা ব্যবহৃত সংস্থার সন্ধান করা হ'ল:

procstat -r `pgrep -x foo`

এখানে, pgrep প্রসেস foo এর PID এক্সট্রাক্ট করতে ব্যবহৃত হয় যা প্রোস্ট্যাট কমান্ডে প্রেরণ করা হয় যা প্রসেসের পিআইডিকে আর্গুমেন্ট হিসাবে প্রত্যাশা করে।

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