मैं आईपी पते की एक लंबी सूची बना रहा हूं, जो क्रम में नहीं हैं। मुझे यह पता लगाने की आवश्यकता है कि किसी विशेष आईपी पते से पहले / बाद में कितने आईपी पते हैं। इसे कैसे प्राप्त किया जा सकता है?
मैं आईपी पते की एक लंबी सूची बना रहा हूं, जो क्रम में नहीं हैं। मुझे यह पता लगाने की आवश्यकता है कि किसी विशेष आईपी पते से पहले / बाद में कितने आईपी पते हैं। इसे कैसे प्राप्त किया जा सकता है?
जवाबों:
शायद सबसे आसान है,
sed -n '/pattern/{=; q;}' file
त्रुटि इंगित करने के लिए @JoshepR को धन्यवाद
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
ewlines का अनुवाद करता है, और में और अन्य सभी में 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
ewlinetr
- जो शून्य को \n
ewlines में तब अनुवाद करता है~/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
वह काम करना चाहिए।