আমার আইপি অ্যাড্রেসের একটি দীর্ঘ তালিকা রয়েছে, যা ক্রমানুসারে নেই। নির্দিষ্ট আইপি ঠিকানার আগে / পরে আমার কতগুলি আইপি ঠিকানা রয়েছে তা সন্ধান করতে হবে। আমি কীভাবে এটি অর্জন করতে পারি?
আমার আইপি অ্যাড্রেসের একটি দীর্ঘ তালিকা রয়েছে, যা ক্রমানুসারে নেই। নির্দিষ্ট আইপি ঠিকানার আগে / পরে আমার কতগুলি আইপি ঠিকানা রয়েছে তা সন্ধান করতে হবে। আমি কীভাবে এটি অর্জন করতে পারি?
উত্তর:
সম্ভবত সবচেয়ে সহজ
sed -n '/pattern/{=; q;}' file
ত্রুটিটি নির্দেশ করার জন্য @ জোশিপআরকে ধন্যবাদ
dc
নিজের কাছে সম্ভবত এটি পাইপ করব।
আমি এই দুটি উপায়ে করেছি, যদিও আমার মনে হয় আমি এইটি সবচেয়ে পছন্দ করি:
: $(( 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
এটি লাইন সংখ্যায় করে:
"$IP"
তারপরে একটি \n
ইলাইনtr
- যা শূন্যগুলিকে \n
ইওলাইনগুলিতে পরে অনুবাদ করে~/file
পার্ল কোডটি এখানে কিছুটা করে যা এটি করে:
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"
$.
কাউন্টারের পরিবর্তে কেন ব্যবহার করবেন না ?
$after
করার চেয়ে বেশি পঠনযোগ্য বলে মনে করি $. - $before
।
$. - 1
, এতে সংরক্ষণ $.
করুন $tmp
। শেষ প্রিন্ট $. - $tmp
। সুতরাং আমাদের আগে এবং পরে উভয়ের জন্য কাউন্টারের দরকার নেই। অবশ্যই এটি আপনার চেয়ে কম পাঠযোগ্য।
আমি নিম্নলিখিত আদেশগুলি চেষ্টা করছিলাম, যা কিছুটা জটিল, তবে সঠিক ফলাফল দেবে:
পরে:
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
Grep
একটি বৈশিষ্ট্য রয়েছে যা নির্দিষ্ট প্যাটার্নটি পাওয়া যায় তার সংখ্যা গণনা করতে পারে। আপনি যদি -c
কমান্ডটি ব্যবহার করেন যা এটি করবে। -c
অ্যান্ড -v
কমান্ডের সাহায্যে এটি গণনা করবে যে এটি কোনও নির্দিষ্ট প্যাটার্নের সাথে কতবার মেলে না
উদাহরণ:
grep -c -v <pattern> file
সুতরাং আপনি যদি কিছু চেষ্টা করে দেখুন:
grep -c -v 192.168.x.x file.log
যে কাজ করা উচিত।