বাশ ব্যবহার করে কলাম দ্বারা কমান্ডের আউটপুট বিভক্ত হবে?


88

আমি এটা করতে চাই:

  1. কমান্ড চালান
  2. আউটপুট ক্যাপচার
  3. একটি লাইন নির্বাচন করুন
  4. এই লাইনের একটি কলাম নির্বাচন করুন

যেমন একটি উদাহরণ হিসাবে ধরা যাক আমি কমান্ডের নামটি একটি থেকে পেতে চাই $PID(দয়া করে এটি একটি উদাহরণ হিসাবে উল্লেখ করুন, আমি প্রস্তাব দিচ্ছি না যে এটি একটি প্রক্রিয়া আইডি থেকে কমান্ড নাম পাওয়ার সবচেয়ে সহজ উপায় - আমার আসল সমস্যাটি হ'ল আর একটি কমান্ড যার আউটপুট ফর্ম্যাটটি আমি নিয়ন্ত্রণ করতে পারি না)।

আমি যদি দৌড়ান তবে psআমি পাই:


  PID TTY          TIME CMD
11383 pts/1    00:00:00 bash
11771 pts/1    00:00:00 ps

এখন আমি করি ps | egrep 11383এবং পেয়েছি

11383 pts/1    00:00:00 bash

পরবর্তী পদক্ষেপ: ps | egrep 11383 | cut -d" " -f 4। আউটপুট হল:

<absolutely nothing/>

সমস্যাটি হ'ল cutএকক স্পেস দ্বারা আউটপুট কেটে যায় এবং psটেবিলের কিছু সাদৃশ্য রাখতে 2 য় এবং 3 য় কলামের মধ্যে কিছু স্পেস যুক্ত করে cutএকটি খালি স্ট্রিং বেছে নেয়। অবশ্যই, আমি cut4 তম ক্ষেত্র নয়, 7 তম নির্বাচন করতে ব্যবহার করতে পারি, তবে কীভাবে আমি জানতে পারি, বিশেষত যখন আউটপুটটি পরিবর্তনশীল এবং অজানা আগে থেকেই থাকে।


4
বিশ্রী (এবং আরও 25 টি অক্ষর) ব্যবহার করুন।
মাইকেল ফুকারাকিস

উত্তর:


179

একটি সহজ উপায় হ'ল যে trকোনও পুনরাবৃত্তি ফিল্ড বিভাজককে বের করে দেওয়ার জন্য একটি পাস যোগ করুন :

$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4

4
আমি এটি পছন্দ করি, দেখতে trআরও হালকা ওজনের চেয়ে বেশিawk
ফ্লাইবায়ার

4
আমি সম্মতি জানাতে চাই, তবে এটি এমনও হতে পারে কারণ আমি বিশ্রী শিখি নি। :)
বিনোদন

আপনি যদি সাবড্রিং হিসাবে আগ্রহী পিআইডি রয়েছে এমন পিআইডি নিয়ে এমন একটি প্রক্রিয়া তৈরি হয় যা কাজ করে না।
ডেভিড গ্রেসন

4
এছাড়াও, যদি কিছু পিআইডি: গুলি স্পেস প্যাড করে অন্যদিকে না থাকে তবে ক্ষেত্রের নুনবারগুলি বন্ধ থাকবে।
ট্রিপলি

68

আমি মনে করি সহজ উপায় হ'ল অজানা ব্যবহার করা । উদাহরণ:

$ echo "11383 pts/1    00:00:00 bash" | awk '{ print $4; }'
bash

4
মূল প্রশ্নের সাথে সামঞ্জস্য করার জন্য, ps | awk "\$1==$PID{print\$4}"বা (আরও ভাল) ps | awk -v"PID=$PID" '$1=PID{print$4}'। অবশ্যই, লিনাক্সে আপনি সহজভাবে করতে পারেন xargs -0n1 </proc/$PID/cmdline | head -n1বা readlink /proc/$PID/exe, তবে যে
কোনও

হয় ;{ print $4; }প্রয়োজনীয়? সরানো হচ্ছে এটা উদ্দেশ্যের সঙ্গে শুধু জানতে আগ্রহী লিনাক্স আমার জন্য কোন প্রভাব আছে বলে মনে হয়,
igniteflow

@ জিগনাইটফ্লো আপনি মুদ্রণ বিবরণীর অতীতে যোগ করা চালিয়ে যেতে চাইলে কমান্ডের শেষটি নির্দেশ করে না?
joshmcode

16

দয়া করে নোট করুন যে tr -s ' 'বিকল্পটি কোনও একক নেতৃস্থানীয় স্পেসগুলি সরাবে না। যদি আপনার কলামটি ডান-সংযুক্ত থাকে ( psপিডের মতো) ...

$ ps h -o pid,user -C ssh,sshd | tr -s " "
 1543 root
19645 root
19731 root

তারপরে কাটাটি সেই প্রথম ক্ষেত্রের কিছু ক্ষেত্রে একটি ফাঁকা রেখার ফলস্বরূপ:

$ <previous command> | cut -d ' ' -f1

19645
19731

আপনি যদি কোনও স্পেস নিয়ে আগে না যান তবে স্পষ্টতই

$ <command> | sed -e "s/.*/ &/" | tr -s " "

এখন, পিড সংখ্যাগুলির এই বিশেষ ক্ষেত্রে (নাম নয়) জন্য একটি ফাংশন রয়েছে pgrep:

$ pgrep ssh


শেল ফাংশন

তবে সাধারণভাবে শেল ফাংশনগুলি সংক্ষিপ্ত পদ্ধতিতে ব্যবহার করা এখনও সম্ভব , কারণ readকমান্ড সম্পর্কে একটি ঝরঝরে জিনিস রয়েছে :

$ <command> | while read a b; do echo $a; done

পড়ার জন্য প্রথম প্যারামিটার, aপ্রথম কলামটি নির্বাচন করে এবং যদি আরও কিছু থাকে তবে অন্য সমস্ত কিছু .োকানো হবে b। ফলস্বরূপ, আপনার কখনই আপনার কলাম +1 এর চেয়ে বেশি ভেরিয়েবলের প্রয়োজন হবে না

সুতরাং,

while read a b c d; do echo $c; done

তারপরে 3 য় কলাম আউটপুট হবে। আমার মন্তব্যে ইঙ্গিত হিসাবে ...

একটি পাইপযুক্ত রিড পরিবেশে কার্যকর করা হবে যা কলিং স্ক্রিপ্টে ভেরিয়েবলগুলি পাস করে না।

out=$(ps whatever | { read a b c d; echo $c; })

arr=($(ps whatever | { read a b c d; echo $c $b; }))
echo ${arr[1]}     # will output 'b'`


অ্যারের সমাধান

সুতরাং আমরা @Frayser এর উত্তরটি শেষ করব যা শেল ভেরিয়েবল আইএফএস ব্যবহার করে যা কোনও স্থানের ডিফল্ট হয়, স্ট্রিংটিকে অ্যারেতে বিভক্ত করে। এটি কেবল বাশে কাজ করে। ড্যাশ এবং অ্যাশ এটি সমর্থন করে না। ব্যাসিবক্স জিনিসটিতে একটি স্ট্রিংকে উপাদানগুলিতে বিভক্ত করতে আমার খুব কষ্ট হয়েছে। একটি একক উপাদান (উদাহরণস্বরূপ awk ব্যবহার করে) পাওয়া এবং তারপরে আপনার প্রয়োজনীয় প্রতিটি প্যারামিটারের জন্য এটি পুনরাবৃত্তি করা যথেষ্ট সহজ। কিন্তু তারপরে আপনি একই লাইনে বার বার অজকে কল করতে বা বার বার একই লাইনে প্রতিধ্বনি সহ একটি রিড ব্লক ব্যবহার করছেন। যা দক্ষ বা সুন্দর নয়। সুতরাং আপনি ব্যবহার করে বিভাজন শেষ ${name%% *}ইত্যাদি। আপনাকে কিছু পাইথন দক্ষতার জন্য আকুল করে তোলে কারণ বাস্তবে শেল স্ক্রিপ্টিং যদি আপনি অভ্যস্ত, অর্ধেক বা আরও বেশি বৈশিষ্ট্যগুলি হারিয়ে যায় তবে আর মজা করা যায় না। তবে আপনি ধরে নিতে পারেন যে এমন একটি সিস্টেমে পাইথনও ইনস্টল করা হবে না এবং এটি ;-) ছিল না।


আপনি পরিবর্তনশীল প্রায় কোট ব্যবহার করা উচিত echo "$a"এবং echo "$c"যদিও।
ট্রিপলি

দেখে মনে হচ্ছে যেন প্রতিটি পাইপযুক্ত ব্লকটি তার নিজের সাবসেল বা প্রক্রিয়াতে চালিত হয় এবং আপনি কোনও পরিবর্তনককে এনক্লোজিং ব্লকে ফিরিয়ে দিতে পারবেন না? যদিও আপনি এটি প্রতিধ্বনির পরে এর আউটপুট পেতে পারেন। var=$(....... | { read a b c d; echo $c; })। এটি কেবলমাত্র একটি একক (স্ট্রিং) জন্য কাজ করে, যদিও বাশে আপনি এটি ব্যবহার করে ar=($var)
এটিটিকে

@ ট্রিপলি আমি মনে করি না যে প্রক্রিয়াটির এমন পর্যায়ে এটি একটি সমস্যা। আপনার প্রয়োজন হবে কিনা তা আপনি খুব শীঘ্রই আবিষ্কার করতে পারবেন এবং যদি এটি কোনও পর্যায়ে ভেঙে যায় তবে এটি একটি শিক্ষণীয় পাঠ। এবং তারপরে আপনি জানবেন কেন আপনাকে এই ডাবল উক্তিগুলি ব্যবহার করতে হয়েছিল ;-)। এবং তারপরে এটি অন্যদের কাছ থেকে বলতে শুনেছেন no আগুন নিয়ে খেলা! : ডি। : পি।
Xennex81


এটি না বলে আমার পক্ষে উত্তরটি খুব সহায়ক ছিল helpful
ইভান এক্স

4

চেষ্টা করুন

ps |&
while read -p first second third fourth etc ; do
   if [[ $first == '11383' ]]
   then
       echo got: $fourth
   fi       
done

4
@ ফ্লাইওয়াইওয়্যার - সম্ভবত এই সাধারণ উদাহরণটির জন্য অতিমাত্রায় দক্ষতা অর্জন করা, তবে আপনাকে নির্বাচিত ডেটাতে আরও জটিল প্রক্রিয়াকরণ করতে হলে এই আইডিয়মটি দুর্দান্ত।
জেমস অ্যান্ডারসন

এছাড়াও, সচেতন থাকুন যে এই দিনগুলিতে ডিফল্ট স্ক্রিপ্টিং শেল সাধারণত বাশ হয় না।
ডেভিড

2

অ্যারে ভেরিয়েবল ব্যবহার করা

set $(ps | egrep "^11383 "); echo $4

বা

A=( $(ps | egrep "^11383 ") ) ; echo ${A[3]}

2

ব্রিয়েনগের অ্যাজক সমাধানের মতো, এখানে পার্ল সমতুল্য:

ps | egrep 11383 | perl -lane 'print $F[3]'

-aঅটোস্প্লিট মোড সক্ষম করে, যা @Fকলামের ডেটা দিয়ে অ্যারেকে পপুলেট করে। আপনার ডেটা স্পেস-সীমাবদ্ধ না হয়ে কমা-বিস্মৃত হলে
ব্যবহার -F,করুন।

পার্ল 1 এর পরিবর্তে 0 থেকে গণনা শুরু করার পরে ফিল্ড 3 মুদ্রিত হয়েছে


4
আপনার পার্ল সমাধানের জন্য আপনাকে ধন্যবাদ - অটোস্প্লিট সম্পর্কে জানতেন না, এবং এখনও পার্লটি অন্য সরঞ্জামগুলি শেষ করার সরঞ্জাম বলে মনে করেন ..;)।
জেরার্ড ওনিল

1

সঠিক লাইন পাওয়া (উদাহরণস্বরূপ line নং লাইনের জন্য) মাথা এবং লেজ দিয়ে সম্পন্ন করা হয়েছে এবং সঠিক শব্দটি (শব্দ নং 4) জোর করে ক্যাপচার করা যেতে পারে:

command|head -n 6|tail -n 1|awk '{print $4}'

ভবিষ্যতের পাঠকদের জন্য কেবল লক্ষ করছি যে awk লাইনের মাধ্যমেও চয়ন করতে awk NR=6 {print $4}পারে : আরও কিছুটা দক্ষ হবে
ডেভিড জেড

4
এবং অবশ্যই আমি বলতে চাইছি awk NR==6 {print $4}"দোহ *
ডেভিড জেড

1

আপনার আদেশ

ps | egrep 11383 | cut -d" " -f 4

tr -sশূন্যস্থানগুলি হ্রাস করতে একটি মিস করে , যেমনটি অনাবৃত তার উত্তরে ব্যাখ্যা করে ।

তবে, আপনি সম্ভবত awkএটি ব্যবহার করতে চান , যেহেতু এটি এই সমস্ত ক্রিয়াটি একটি একক আদেশে পরিচালনা করে:

ps | awk '/11383/ {print $4}'

এটি থাকা লাইনগুলিতে এটি চতুর্থ কলাম প্রিন্ট করে 11383। আপনি 11383যদি এটির সাথে মিল রাখতে চান যদি এটি লাইনের শুরুতে উপস্থিত হয়, তবে আপনি বলতে পারেন ps | awk '/^11383/ {print $4}'


0

এই সমস্ত গ্রেপস এবং স্টাফ না করে, আমি আপনাকে আউটপুট ফর্ম্যাট পরিবর্তনের PS ক্ষমতা ব্যবহার করার পরামর্শ দেব।

ps -o cmd= -p 12345

নির্দিষ্ট পিডের সাথে আপনি কোনও প্রক্রিয়ার সেন্টিম্যান্ড লাইন পাবেন এবং অন্য কিছুই নয়।

এটি পসিক্স-কনফর্মেন্ট এবং এটি বহনযোগ্য হিসাবে বিবেচিত হতে পারে।


4
ফ্লাইবায়ার বলেছেন যে তিনি কেবল উদাহরণ হিসাবে PS ব্যবহার করছেন, প্রশ্নটি তার চেয়ে বেশি সাধারণ।
ওগ্রে গীতসংহিতা 33

0

বাশের set অবস্থান পরামিতি সব আউটপুট বিশ্লেষণ করতে হবে।

উদাহরণস্বরূপ, set $(free -h)কমান্ড সহ, echo $7"মেমো:" প্রদর্শন করবে


এই পদ্ধতিটি তখনই কার্যকর যখন কমান্ডের আউটপুটের একক লাইন থাকে। যথেষ্ট জেনেরিক নয়।
কোডফোরস্টার

এটি সত্য নয়, লাইন নির্বিশেষে সমস্ত আউটপুট অবস্থানগত পরামিতিগুলিতে স্থাপন করা হয়। প্রাক্তন set $(sar -r 1 1); echo "${23}"
dman

আমার বক্তব্যটি ছিল যে আউটপুটটি পরিমাণমতো হয় এবং তার অনেক ক্ষেত্র থাকে তখন যুক্তির অবস্থান নির্ধারণ করা শক্ত। awkএটি সম্পর্কে সবচেয়ে ভাল উপায়।
কোডফোরস্টার

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