কোনও ফাইলের পাঠ্যের উপস্থিতিগুলি কীভাবে গণনা করবেন?


19

আমার আইপি অ্যাড্রেস অনুসারে একটি লগ ফাইল রয়েছে, আমি প্রতিটি অনন্য আইপি ঠিকানার সংখ্যার সন্ধান করতে চাই। আমি কীভাবে বাশ দিয়ে এটি করতে পারি? সম্ভবত কোনও আইপি-র পাশে সংঘটনগুলির সংখ্যা তালিকাবদ্ধ করা যেমন:

5.135.134.16 count: 5
13.57.220.172: count 30
18.206.226 count:2

ইত্যাদি।

লগের একটি নমুনা এখানে:

5.135.134.16 - - [23/Mar/2019:08:42:54 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:55 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:55 -0400] "POST /wp-login.php HTTP/1.1" 200 3836 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:55 -0400] "POST /wp-login.php HTTP/1.1" 200 3988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:56 -0400] "POST /xmlrpc.php HTTP/1.1" 200 413 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:05 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:06 -0400] "POST /wp-login.php HTTP/1.1" 200 3985 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:07 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:08 -0400] "POST /wp-login.php HTTP/1.1" 200 3833 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:09 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:11 -0400] "POST /wp-login.php HTTP/1.1" 200 3836 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:12 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:15 -0400] "POST /wp-login.php HTTP/1.1" 200 3837 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:17 -0400] "POST /xmlrpc.php HTTP/1.1" 200 413 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.233.99 - - [23/Mar/2019:04:17:45 -0400] "GET / HTTP/1.1" 200 25160 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
18.206.226.75 - - [23/Mar/2019:21:58:07 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "https://www.google.com/url?3a622303df89920683e4421b2cf28977" "Mozilla/5.0 (Windows NT 6.2; rv:33.0) Gecko/20100101 Firefox/33.0"
18.206.226.75 - - [23/Mar/2019:21:58:07 -0400] "POST /wp-login.php HTTP/1.1" 200 3988 "https://www.google.com/url?3a622303df89920683e4421b2cf28977" "Mozilla/5.0 (Windows NT 6.2; rv:33.0) Gecko/20100101 Firefox/33.0"
18.213.10.181 - - [23/Mar/2019:14:45:42 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
18.213.10.181 - - [23/Mar/2019:14:45:42 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
18.213.10.181 - - [23/Mar/2019:14:45:42 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"

1
"বাশ" দিয়ে আপনি কি সাধারণ প্লেল শেল বা কমান্ড লাইনটি সাধারণভাবে বোঝাতে চাইছেন?
মিষ্টান্ন

1
আপনার কি ব্যবহারের জন্য কোনও ডাটাবেস সফ্টওয়্যার উপলব্ধ?
স্পেসফিনিক্স


লগটি একটি অ্যাপে 2 সার্ভার থেকে এসেছে, আসলে কোনও ডাটাবেস নয়। বাশ হ'ল আমি সাধারণ ব্যবহারের ক্ষেত্রে পছন্দ করি। আমি অজগর এবং পার্ল সমাধানগুলি দেখতে পাচ্ছি, যদি তারা অন্য কারও পক্ষে ভাল হয় তবে তা দুর্দান্ত। প্রাথমিক বাছাইটি করা হয়েছিল sort -Vযদিও আমি মনে করি এটি প্রয়োজনীয় ছিল না। আমি লগইন পৃষ্ঠার শীর্ষ 10 আপত্তিজনককে সংশ্লিষ্ট সাবনেট নিষিদ্ধ করার জন্য সুপারিশ সহ সিস্টেম প্রশাসকের কাছে প্রেরণ করেছি। উদাহরণস্বরূপ, একটি আইপি 9000 বারের মধ্যে লগইন পৃষ্ঠায় আঘাত করেছে। সেই আইপি, এবং এর ক্লাস ডি সাবনেটটি এখন কালো তালিকাভুক্ত। আমি নিশ্চিত যে আমরা এটি স্বয়ংক্রিয় করতে পারি, যদিও এটি একটি ভিন্ন প্রশ্ন।
j0h

উত্তর:


13

আপনি ব্যবহার করতে পারেন grepএবং uniqঠিকানাগুলির তালিকার জন্য, সেগুলি থেকে লুপ এবং grepআবার গণনার জন্য:

for i in $(<log grep -o '^[^ ]*' | uniq); do
  printf '%s count %d\n' "$i" $(<log grep -c "$i")
done

grep -o '^[^ ]*'প্রতিটি অক্ষরের শুরু ( ^) থেকে প্রতিটি লাইনের প্রথম স্থান পর্যন্ত আউটপুট uniqদেয়, পুনরাবৃত্ত লাইনগুলি সরিয়ে দেয়, সুতরাং আপনাকে আইপি অ্যাড্রেসের একটি তালিকা রেখে দেয়। কমান্ড প্রতিস্থাপনের জন্য ধন্যবাদ, forবর্তমানে প্রক্রিয়াজাত আইপি "কাউন্ট" এবং গণনা অনুসরণ করে এই তালিকাটির উপরে লুপ লুপ করে। পরেরটি দ্বারা গুণ করা হয় grep -c, যা কমপক্ষে একটি ম্যাচের সাথে লাইনের সংখ্যা গণনা করে।

উদাহরণ রান

$ for i in $(<log grep -o '^[^ ]*'|uniq);do printf '%s count %d\n' "$i" $(<log grep -c "$i");done
5.135.134.16 count 5
13.57.220.172 count 9
13.57.233.99 count 1
18.206.226.75 count 2
18.213.10.181 count 3

13
এই সমাধানটি প্রতিটি আইপি ঠিকানার জন্য একবার ইনপুট ফাইলটির উপরে বারবার পুনরাবৃত্তি করে, যা ফাইলটি বড় হলে খুব ধীর হবে। অন্যান্য সমাধানগুলি ব্যবহার করে uniq -cবা awkকেবলমাত্র একবার ফাইলটি পড়তে হবে
ডেভিড

1
@ ডেভিড এটি সত্য, তবে গ্রীপ গণনা জেনে এটিও আমার প্রথম এটি হতে পারে। যদি না পারফরম্যান্স পরিমাপযোগ্য কোনও সমস্যা না হয় ... অকালে অপ্টিমাইজ করবেন না?
ডি বেন নোবল

3
আরও দক্ষ সমাধানটি আরও সহজ, তবে প্রতিটি তাদের নিজস্ব বলে আমি এটি একটি অকাল অপটিমাইজেশন বলব না।
ডেভিড

যাইহোক, এটি কেন <log grep ...এবং হিসাবে লিখিত হয় না grep ... log?
সান্টিয়াগো


39

আপনি ব্যবহার করতে পারেন cutএবং uniqসরঞ্জামগুলি:

cut -d ' ' -f1 test.txt  | uniq -c
      5 5.135.134.16
      9 13.57.220.172
      1 13.57.233.99
      2 18.206.226.75
      3 18.213.10.181

ব্যাখ্যা:

  • cut -d ' ' -f1 : প্রথম ক্ষেত্রটি বের করুন (আইপি ঠিকানা)
  • uniq -c : পুনরাবৃত্তি লাইন রিপোর্ট এবং উপস্থিতি সংখ্যা প্রদর্শন

6
একটি sedযেমন sed -E 's/ *(\S*) *(\S*)/\2 count: \1/'ওপি চেয়েছিল ঠিক একইভাবে আউটপুট পেতে ব্যবহার করতে পারে ।
মিষ্টান্ন

2
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, যেহেতু মিষ্টান্নের দ্বারা বার বার ফাইলটি পড়া দরকার তাই খুব ধীর। sort file | cut .... ফাইলটি ইতিমধ্যে বাছাই করা হয়েছে কিনা তা আপনি নিশ্চিত না হলে আপনি সহজেই ব্যবহার করতে পারেন ।
গুন্ট্রাম ব্লহম মনিকা

14

যদি আপনার নির্দিষ্টভাবে প্রদত্ত আউটপুট বিন্যাসের প্রয়োজন না হয় তবে আমি ইতিমধ্যে পোস্ট করা + ভিত্তিক উত্তরটি সুপারিশ করবcutuniq

আপনার যদি সত্যিই প্রদত্ত আউটপুট ফর্ম্যাটটির প্রয়োজন হয় তবে এটিকে ওউকে করার একটি একক-পাস উপায় হবে be

awk '{c[$1]++} END{for(i in c) print i, "count: " c[i]}' log

এটি কিছুটা আদর্শহীন যখন ইনপুটটি ইতিমধ্যে বাছাই করা হয় কারণ এটি অযথা সমস্ত আইপি মেমরিতে সংরক্ষণ করে - একটি আরও ভাল, যদিও আরও জটিল, প্রাক-সাজানো ক্ষেত্রে এটি করার উপায় হবে (আরও সরাসরি সমতুল্য uniq -c):

awk '
  NR==1 {last=$1} 
  $1 != last {print last, "count: " c[last]; last = $1} 
  {c[$1]++} 
  END {print last, "count: " c[last]}
'

যাত্রা।

$ awk 'NR==1 {last=$1} $1 != last {print last, "count: " c[last]; last = $1} {c[$1]++} END{print last, "count: " c[last]}' log
5.135.134.16 count: 5
13.57.220.172 count: 9
13.57.233.99 count: 1
18.206.226.75 count: 2
18.213.10.181 count: 3

দাবিযুক্ত ফর্ম্যাটটিতে উপস্থিত হয়ে কাটা + ইউনিট ভিত্তিক উত্তরটি সেডের সাথে পরিবর্তন করা সহজ হবে।
পিটার -

@ পিটারএ.স্নাইডার হ্যাঁ এটি করবে - আমি বিশ্বাস করি যে ইতিমধ্যে উত্তরটির মন্তব্যে চিহ্নিত করা হয়েছিল
স্টিল্ড্রাইভার


8

এখানে একটি সম্ভাব্য সমাধান:

IN_FILE="file.log"
for IP in $(awk '{print $1}' "$IN_FILE" | sort -u)
do
    echo -en "${IP}\tcount: "
    grep -c "$IP" "$IN_FILE"
done
  • file.logপ্রকৃত ফাইলের নাম দিয়ে প্রতিস্থাপন করুন।
  • কমান্ড প্রতিস্থাপনের এক্সপ্রেশনটি $(awk '{print $1}' "$IN_FILE" | sort -u)প্রথম কলামের অনন্য মানের একটি তালিকা সরবরাহ করবে।
  • তারপরে grep -cফাইলের মধ্যে এই প্রতিটি মান গণনা করবে।

$ IN_FILE="file.log"; for IP in $(awk '{print $1}' "$IN_FILE" | sort -u); do echo -en "${IP}\tcount: "; grep -c "$IP" "$IN_FILE"; done
13.57.220.172   count: 9
13.57.233.99    count: 1
18.206.226.75   count: 2
18.213.10.181   count: 3
5.135.134.16    count: 5

1
পছন্দ printf...
ডি বেন Knoble

1
এর অর্থ আপনাকে পুরো ফাইলটি একাধিকবার প্রক্রিয়া করতে হবে। একবার আইপিগুলির তালিকা পেতে এবং তারপরে আপনি খুঁজে পাওয়া প্রতিটি আইপিগুলির জন্য আরও একবার।
টেরডন

5

কিছু পার্ল:

$ perl -lae '$k{$F[0]}++; }{ print "$_ count: $k{$_}" for keys(%k)' log 
13.57.233.99 count: 1
18.206.226.75 count: 2
13.57.220.172 count: 9
5.135.134.16 count: 5
18.213.10.181 count: 3

এটি স্টিল্ড্রাইভারের অ্যাজক পদ্ধতির মতো একই ধারণা , তবে পার্লে। -aকারণ স্বয়ংক্রিয়ভাবে অ্যারের প্রতিটি ইনপুট লাইন বিভক্ত করতে Perl @F, যার প্রথম উপাদান (আইপি) হল $F[0]। সুতরাং, $k{$F[0]}++হ্যাশ তৈরি করবে %k, যার কীগুলি আইপি এবং যার মান প্রতিটি আইপি কতবার দেখা হয়েছিল। }{"সমস্ত ইনপুট প্রক্রিয়াকরণের পরে খুব শেষে বাকি কাজ," এর জন্য ভীতু perlspeak হয়। সুতরাং, শেষে, স্ক্রিপ্টটি হ্যাশগুলির কীগুলির সাথে পুনরাবৃত্তি করবে এবং $_তার মান ( $k{$_}) সহ বর্তমান কী ( ) প্রিন্ট করবে ।

এবং, ঠিক তাই লোকেরা মনে করে না যে পার্ল আপনাকে স্ক্রিপ্ট লিখতে বাধ্য করে যা ক্রিপ্টিক স্ক্রিবিবলিংয়ের মতো দেখায়, এটি কম ঘনীভূত আকারে একই জিনিস:

perl -e '
  while (my $line=<STDIN>){
    @fields = split(/ /, $line);
    $ip = $fields[0];
    $counts{$ip}++;
  }
  foreach $ip (keys(%counts)){
    print "$ip count: $counts{$ip}\n"
  }' < log

4

ওপিও হয়ত এটি চায় না; তবে, যদি আমরা জানি যে আইপি ঠিকানার দৈর্ঘ্য 15 টি অক্ষরের মধ্যে সীমাবদ্ধ থাকবে, তবে একটি বিশাল লগ ফাইল থেকে অনন্য আইপি সহ গণনাগুলি প্রদর্শন করার দ্রুত উপায়টি uniqকেবলমাত্র কমান্ড ব্যবহার করেই অর্জন করা যেতে পারে :

$ uniq -w 15 -c log

5 5.135.134.16 - - [23/Mar/2019:08:42:54 -0400] ...
9 13.57.220.172 - - [23/Mar/2019:11:01:05 -0400] ...
1 13.57.233.99 - - [23/Mar/2019:04:17:45 -0400] ...
2 18.206.226.75 - - [23/Mar/2019:21:58:07 -0400] ...
3 18.213.10.181 - - [23/Mar/2019:14:45:42 -0400] ...

বিকল্প:

-w NNলাইনগুলিতে অক্ষরের চেয়ে আর কোনও তুলনা করা হয় না

-c সংঘটন সংখ্যার দ্বারা লাইন উপসর্গ করা হবে

বিকল্পভাবে, সঠিক বিন্যাসিত আউটপুটটির জন্য আমি পছন্দ করি awk(আইপিভি 6 ঠিকানাগুলির জন্যও কাজ করা উচিত), ymmv।

$ awk 'NF { print $1 }' log | sort -h | uniq -c | awk '{printf "%s count: %d\n", $2,$1 }'

5.135.134.16 count: 5
13.57.220.172 count: 9
13.57.233.99 count: 1
18.206.226.75 count: 2
18.213.10.181 count: 3

নোট করুন যে uniqইনপুট ফাইলটিতে পুনরাবৃত্তি করা লাইনগুলি যদি সংলগ্ন না হয় তবে এটি সনাক্ত করবে না, সুতরাং এটি sortফাইলের জন্য প্রয়োজনীয় হতে পারে ।


1
অনুশীলনে সম্ভবত যথেষ্ট ভাল, তবে কোণার কেসগুলি লক্ষ্য করার মতো। আইপি after - - [`এর পরে কেবল 6 টি সম্ভবত ধ্রুব অক্ষর` তবে তাত্ত্বিকভাবে ঠিকানাটি সর্বোচ্চের চেয়ে 8 টি অক্ষর পর্যন্ত কম হতে পারে তাই তারিখের পরিবর্তনের ফলে এই জাতীয় আইপির জন্য গণনা বিভক্ত হতে পারে। এবং যেমন আপনি ইঙ্গিত করেছেন, এটি আইপিভি 6 এর জন্য কাজ করবে না।
মার্টিন থর্নটন

আমি এটি পছন্দ করি, আমি জানতাম না যে ইউনিক গণনা করতে পারে!
j0h

1

এফডাব্লুআইডাব্লু, পাইথন 3:

from collections import Counter

with open('sample.log') as file:
    counts = Counter(line.split()[0] for line in file)

for ip_address, count in counts.items():
    print('%-15s  count: %d' % (ip_address, count))

আউটপুট:

13.57.233.99     count: 1
18.213.10.181    count: 3
5.135.134.16     count: 5
18.206.226.75    count: 2
13.57.220.172    count: 9

0
cut -f1 -d- my.log | sort | uniq -c

ব্যাখ্যা: ড্যাশগুলিতে মাই.লগ বিভাজনের প্রথম ক্ষেত্রটি নিয়ে -তা সাজান। uniqবাছাই করা ইনপুট দরকার। -cঘটনাগুলি গণনা করতে বলে।

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