একটি মাল্টি লাইন গ্রেপ সঞ্চালন কিভাবে


15

আপনি দুটি লাইনে প্রদর্শিত পাঠ্যের জন্য কীভাবে গ্রিপ সম্পাদন করবেন?

উদাহরণ স্বরূপ:

pbsnodes আমি যে কমান্ডটি ব্যবহার করি এটি লিনাক্স ক্লাস্টারের ব্যবহার ফিরিয়ে দেয়

root$ pbsnodes
node1
    state = free
    procs = 2
    bar = foobar

node2
    state = free
    procs = 4
    bar = foobar

node3
    state = busy
    procs = 8
    bar = foobar

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

উপরের উদাহরণে, সঠিক উত্তরটি হবে 6 (2 + 4)।

আমি কি আছে

root$ NUMBEROFNODES=`pbsnodes|grep 'state = free'|wc -l`
root$ echo $NUMBEROFNODES
2

root$ NUMBEROFPROCS=`pbsnodes |grep "procs = "|awk  '{ print $3 }' | awk '{ sum+=$1 } END { print sum }'`
root$ echo $NUMBEROFPROCS
14

'Procs = x' পড়ার মতো প্রতিটি লাইনের জন্য আমি কীভাবে অনুসন্ধান করতে পারি, তবে কেবল তার উপরের রেখাটি যদি 'state = free' পড়ে থাকে তবে?

উত্তর:


12

ডেটা যদি সর্বদা সেই বিন্যাসে থাকে তবে আপনি কেবল এটি লিখতে পারেন:

awk -vRS= '$4 == "free" {n+=$7}; END {print n}'

( RS=মানে রেকর্ডগুলি অনুচ্ছেদে )।

বা:

awk -vRS= '/state *= *free/ && match($0, "procs *=") {
  n += substr($0,RSTART+RLENGTH)}; END {print n}'

5
$ pbsnodes
node1
    state = free
    procs = 2
    bar = foobar

node2
    state = free
    procs = 4
    bar = foobar

node3
    state = busy
    procs = 8
    bar = foobar
$ pbsnodes | grep -A 1 free
    state = free
    procs = 2
--
    state = free
    procs = 4
$ pbsnodes | grep -A 1 free | grep procs | awk '{print $3}'
2
4
$ pbsnodes | grep -A 1 free | grep procs | awk '{print $3}' | paste -sd+ 
2+4
$ pbsnodes | grep -A 1 free | grep procs | awk '{print $3}' | paste -sd+ | bc 
6

https://en.wikipedia.org/wiki/Pipeline_(Unix)


4

এটি ব্যবহার করে করার একটি উপায় এখানে pcregrep

$ pbsnodes | pcregrep -Mo 'state = free\n\s*procs = \K\d+'
2
4

উদাহরণ

$ pbsnodes | \
    pcregrep -Mo 'state = free\n\s*procs = \K\d+' | \
    awk '{ sum+=$1 }; END { print sum }'
6

3

আপনার আউটপুট ফর্ম্যাটটি পার্লের অনুচ্ছেদে স্লাপের জন্য তৈরি করা হয়েছে:

pbsnodes|perl -n00le 'BEGIN{ $sum = 0 }
                 m{
                   state \s* = \s* free \s* \n 
                   procs \s* = \s* ([0-9]+)
                 }x 
                    and $sum += $1;
                 END{ print $sum }'

বিঃদ্রঃ

এটি কেবলমাত্র কাজ করে কারণ পার্লের "অনুচ্ছেদে" ধারণাটি এক বা একাধিক ফাঁকা রেখার দ্বারা পৃথক করা খালি খালি লাইনের একটি অংশ। nodeবিভাগগুলির মধ্যে যদি আপনার ফাঁকা রেখা না থাকে তবে এটি কাজ করবে না।

আরো দেখুন


3

আপনার যদি একটি নির্দিষ্ট দৈর্ঘ্যের ডেটা থাকে (কোনও রেকর্ডে রেখার সংখ্যা উল্লেখ করে নির্দিষ্ট দৈর্ঘ্য), আপনি কমান্ডটি sedব্যবহার করতে পারেন N(বেশ কয়েকবার), যা পরের লাইনে প্যাটার্ন স্পেসে যোগ দেয়:

sed -n '/^node/{N;N;N;s/\n */;/g;p;}'

আপনি যেমন আউটপুট দিতে হবে:

node1;state = free;procs = 2;bar = foobar
node2;state = free;procs = 4;bar = foobar
node3;state = busy;procs = 8;bar = foobar

পরিবর্তনশীল রেকর্ড রচনার জন্য (যেমন একটি খালি বিভাজক লাইন সহ), আপনি ব্রাঞ্চিং কমান্ড ব্যবহার করতে পারেন tএবং b, তবে awkসম্ভবত আপনাকে আরও আরামদায়ক উপায়ে পাবেন।


3

GNU বাস্তবায়ন grepদুটি আর্গুমেন্ট নিয়ে আসে একটি ম্যাচের আগে ( -B) এবং পরে ( -A) পরে লাইনগুলি মুদ্রণ করতে । ম্যান পৃষ্ঠা থেকে স্নিপেট:

   -A NUM, --after-context=NUM
          Print NUM lines of trailing context after matching lines.  Places a line containing  a  group  separator  (--)  between  contiguous  groups  of  matches.   With  the  -o  or
          --only-matching option, this has no effect and a warning is given.

   -B NUM, --before-context=NUM
          Print  NUM  lines  of  leading  context  before  matching  lines.   Places  a  line  containing  a group separator (--) between contiguous groups of matches.  With the -o or
          --only-matching option, this has no effect and a warning is given.

সুতরাং আপনার ক্ষেত্রে, আপনাকে state = freeনীচের লাইনটি গ্রেপ করতে হবে এবং মুদ্রণ করতে হবে। আপনার প্রশ্ন থেকে স্নিপেটগুলির সাথে এটি মিশ্রন করে আপনি এমন কিছুতে পৌঁছবেন:

usr@srv % pbsnodes | grep -A 1 'state = free' | grep "procs = " | awk  '{ print $3 }' | awk '{ sum+=$1 } END { print sum }'
6

এবং কিছুটা খাটো:

usr@srv % pbsnodes | grep -A 1 'state = free' | awk '{ sum+=$3 } END { print sum }'
6

awkপ্যাটার্ন মিলছে; আপনার প্রয়োজন নেই grep:
স্টিফেনের

ওয়েল, sedপাশাপাশি প্যাটার্ন মেলানো হয়। আপনি perl, বা php, বা আপনার পছন্দ মতো কোন ভাষা ব্যবহার করতে পারেন । তবে কমপক্ষে প্রশ্নের শিরোনামটি মাল্টি লাইনের
গ্রেপ চেয়েছিল

হ্যাঁ: তবে আপনি awkযেভাবেই ব্যবহার করছেন তা দেখে ... :)
জেসনওয়ারিয়ান

0

... এবং এখানে একটি পার্ল সমাধান:

pbsnodes | perl -lne 'if (/^\S+/) { $node = $& } elsif ( /state = free/ ) { print $node }'

0

আপনি awk getlineকমান্ডটি ব্যবহার করতে পারেন :

$ pbsnodes | awk 'BEGIN { freeprocs = 0 } \
                  $1=="state" && $3=="free" { getline; freeprocs+=$3 } \
                  END { print freeprocs }'

থেকে man awk :

   getline               Set $0 from next input record; set NF, NR, FNR.

   getline <file         Set $0 from next record of file; set NF.

   getline var           Set var from next input record; set NR, FNR.

   getline var <file     Set var from next record of file.

   command | getline [var]
                         Run command piping the output either into $0 or var, as above.

   command |& getline [var]
                         Run  command  as a co-process piping the output either into $0 or var, as above.  Co-processes are a
                         gawk extension.
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.