কোনও প্যাটার্ন ম্যাচের আগে / পরে মোট লাইন সংখ্যা গণনা করুন


9

আমার আইপি অ্যাড্রেসের একটি দীর্ঘ তালিকা রয়েছে, যা ক্রমানুসারে নেই। নির্দিষ্ট আইপি ঠিকানার আগে / পরে আমার কতগুলি আইপি ঠিকানা রয়েছে তা সন্ধান করতে হবে। আমি কীভাবে এটি অর্জন করতে পারি?


আপনার কি নকল আইপি আছে?
cuonglm

সমস্ত আইপি অ্যাড্রেস অনন্য।
মন্দার শিন্ডে

আইপি ঠিকানার আগে / পরে অর্থ কী? বিশেষত, আপনার কি আইপিভি 4 এবং আইপিভি 6 ঠিকানা রয়েছে? তারা কীভাবে তুলনা করবে?
ভিঙ্ক 17

আপনার ফাইল বাছাই করা দরকার?
cuonglm

2
@ ভিনক 17 - ফাইলটিতে কেবল আইপি ঠিকানা থাকে (আইপিভি 4), অন্য কোনও ডেটা অন্তর্ভুক্ত থাকে না। যদি মোট 1000 আইপি ঠিকানা থাকে এবং ম্যাচটি 300 তম স্থানে পাওয়া যায়, মানে ম্যাচের আগে 299 লাইন এবং ম্যাচের পরে 700 লাইন রয়েছে।
মন্দার শিন্ডে

উত্তর:


8

ম্যাচের আগে এবং পরে লাইনগুলির সংখ্যা, ম্যাচ সহ (যেমন আপনি ম্যাচটি বাদ দিতে চান তবে আপনাকে ফলাফল থেকে 1 টি বিয়োগ করতে হবে):

sed -n '0,/pattern/p' file | wc -l
sed -n '/pattern/,$p' file | wc -l

তবে বিশেষ করে আইপি অ্যাড্রেসের সাথে এর কোনও যোগসূত্র নেই।


4

সম্ভবত সবচেয়ে সহজ

sed -n '/pattern/{=; q;}' file

ত্রুটিটি নির্দেশ করার জন্য @ জোশিপআরকে ধন্যবাদ


এটি কেবল লাইন নম্বরটি মুদ্রণ করে যার উপর প্যাটার্নটি ঘটেছে।
জোসেফ আর।

@JosephR। - না, এটি প্রতিটি লাইন নম্বর মুদ্রণ করে যার উপর প্রতিটি ম্যাচ ঘটে।
মাইকসার্ভ

@ মিকসার্ভ আমি জানি তবে ওপি নির্দিষ্ট করে দিয়েছে যে আইপি ঠিকানাগুলি অনন্য unique ওপিতে লাইন নম্বরটিও চায় না যেখানে ম্যাচটি হয়েছে (গুলি); তারা চান লাইনের সংখ্যা সামনে প্যাটার্ন ঘটেছে এবং পরে লাইন সংখ্যা।
জোসেফ আর।

@ জোসেফআর - এই গণনাগুলিতে পৌঁছানোর দ্রুততম উপায় হ'ল লাইন সংখ্যাগুলি টালাই - আমি কেবল dcনিজের কাছে সম্ভবত এটি পাইপ করব।
মাইকজার্ভ

@ মিকসার্ভ আমি যুক্তি দিচ্ছি না যে এই উত্তর থেকে প্রাপ্ত তথ্য কার্যকর নয়, আমি কেবল বলছি যে এই কোডটি নিজে থেকে ওপি যা চায় তা করে না।
জোসেফ আর।

3

আমি এই দুটি উপায়ে করেছি, যদিও আমার মনে হয় আমি এইটি সবচেয়ে পছন্দ করি:

: $(( afterl=( lastl=$(wc -l <~/file) ) - 2 -
  $(( beforel=( matchl=$(sed -n "/$IP/{=;q;}" <~/file) ) - 1
)) ))
for n in last match afters befores
do  printf '%s line%s :\t%d\n' \
        "${n%s}" "${n##*[!s]}" $((${n%s}l))
done

এটি তাদের বর্তমান শেল ভেরিয়েবল হিসাবে সংরক্ষণ করে - এবং আউটপুট জন্য লুপের জন্য পরে তাদের মূল্যায়ন করে। এটি দিয়ে ফাইলের মোট লাইন গণনা করে wcএবং এর সাথে প্রথম মিলিত লাইন নম্বর পায় sed

এর আউটপুট:

last line :     1000
match line :    200
after lines :   799
before lines :  199

আমিও করেছি:

sed -n "/$IP/=;\$=" ~/file |  
tr \\n \  | { 
IFS=' ' read ml ll 
printf '%s line%s:\t%d\n' \
    last '' $((ll=${ll##* }))
    match '' $ml \
    after s "$((al=ll-ml-1)) \ 
    before s $((bl=ml-1))
}

sedকেবল মিল এবং শেষ লাইন নম্বরগুলি মুদ্রণ করে, তারপরে trইন্টারভেনিং \nইওলাইনগুলিতে অনুবাদ করে, এবং এর ফলাফলগুলির মধ্যে readপ্রথমটি sedপড়ে $mlএবং অন্যদের মধ্যে পড়ে $ll। সম্ভাব্য একাধিক ম্যাচের কেসগুলি সমস্ত এড়িয়ে গিয়ে শেষ $llকরা হয়েছে, পরে এটিকে পুনরায় সেট করার সময় শেষ প্রসারণের বাইরে ।

এর আউটপুট:

last line :     1000
match line :    200
after lines :   799
before lines :  199

উভয় পদ্ধতি নিম্নলিখিত পদ্ধতিতে উত্পন্ন ফাইলটিতে পরীক্ষা করা হয়েছিল:

IP='some string for which I seek' 
for count in 1 2 3 4 5 
do  printf '%.199d%s\n' 0 "$IP" 
done | tr 0 \\n >~/file 

এটি লাইন সংখ্যায় করে:

  1. অনুসন্ধানের স্ট্রিং সেট করে
  2. একাধিক ম্যাচ হবে তা নিশ্চিত করতে পাঁচবার লুপ করুন
  3. ১৯৯ টি শূন্যগুলি প্রিন্ট করে "$IP"তারপরে একটি \nইলাইন
  4. পাইপ আউটপুট এতে tr- যা শূন্যগুলিকে \nইওলাইনগুলিতে পরে অনুবাদ করে~/file

2

পার্ল কোডটি এখানে কিছুটা করে যা এটি করে:

perl -ne '
     if(1 .. /192\.168\.1\.1/) { $before++ }
     else                      { $after++  }
     $before--; # The matching line was counted
     END{print "Before: $before, After: $after\n"}' your_file

এটি আইপিযুক্ত লাইনের আগে এবং পরে মোট লাইন সংখ্যা গণনা করে 192.168.1.1। আপনার পছন্দসই আইপি দিয়ে প্রতিস্থাপন করুন।

বাশ ছাড়া কিছুই ব্যবহার করা হচ্ছে না:

before=0
match=0
after=0
while read line;do
    if [ "$line" = 192.168.1.1 ];then
        match=1
    elif [ $match -eq 0 ];then
        before=$(($before+1))
    else
        after=$(($after + 1))
    fi
done < your_file
printf "Before: %d, After: %d\n" "$before" "$after"

বেস পছন্দ হয়।
মন্দার শিন্দে

2
@ জোসেফ আর: আপনি $.কাউন্টারের পরিবর্তে কেন ব্যবহার করবেন না ?
cuonglm

@ জ্নোক আমি অবশ্যই পারতাম। আমি কেবল এটি সেট $afterকরার চেয়ে বেশি পঠনযোগ্য বলে মনে করি $. - $before
জোসেফ আর।

না, আমি বলতে চাইছি: যদি মিলে যায় তবে মুদ্রণ করুন $. - 1, এতে সংরক্ষণ $.করুন $tmp। শেষ প্রিন্ট $. - $tmp। সুতরাং আমাদের আগে এবং পরে উভয়ের জন্য কাউন্টারের দরকার নেই। অবশ্যই এটি আপনার চেয়ে কম পাঠযোগ্য।
cuonglm

@ মান্দারশিন্দে দয়া করে সম্পাদনা দেখুন। আমি একটি খাঁটি বাশ উত্তর যুক্ত করেছি।
জোসেফ আর।

2

আমি নিম্নলিখিত আদেশগুলি চেষ্টা করছিলাম, যা কিছুটা জটিল, তবে সঠিক ফলাফল দেবে:

পরে:

a=$(cat file | wc -l) && b=$(cat -n file | grep <Pattern> | awk '{print $1}') && echo "$a - $b" | bc -l

আগে:

echo "`cat -n file | grep <Pattern> | awk '{print $1}'`-1" | bc -l

2

একটি awkসমাধান আগে ও শেষ ম্যাচ পর প্রতিবেদন লাইনের সংখ্যা

awk '/192\.168\.1\.1/{x=NR};{y=NR} END{printf "before-%d, after-%d\n" , x-1, y-x}'  file

1

Grepএকটি বৈশিষ্ট্য রয়েছে যা নির্দিষ্ট প্যাটার্নটি পাওয়া যায় তার সংখ্যা গণনা করতে পারে। আপনি যদি -cকমান্ডটি ব্যবহার করেন যা এটি করবে। -cঅ্যান্ড -vকমান্ডের সাহায্যে এটি গণনা করবে যে এটি কোনও নির্দিষ্ট প্যাটার্নের সাথে কতবার মেলে না

উদাহরণ:

grep -c -v <pattern> file

সুতরাং আপনি যদি কিছু চেষ্টা করে দেখুন:

grep -c -v 192.168.x.x file.log যে কাজ করা উচিত।


এটি লক্ষ্য আইপির সংখ্যার সংখ্যা গণনা করে। এটি ওপি যা চেয়েছিল তা নয়।
জোসেফ আর।

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