1. 概要

長いリストを含むファイルからIPアドレスを抽出する必要がある場合があります。 これは、たとえば、サーバーのアクセスログファイルからのものである可能性があります。

このチュートリアルでは、ファイルからIPv4アドレスを抽出するために使用できるさまざまな方法について説明します。

2. 設定

アクセスログファイルの数行を含むファイルsample.logを作成しましょう。

$ touch sample.log

次に、Nanoエディターで開きます。

$ nano sample.log

次に、これらのログエントリを貼り付けて、ファイルを保存しましょう。

13.66.139.0 - - [19/Dec/2020:13:57:26 +0100] "GET /index.php?option=com_phocagallery&view=category&id=1:almhuette-raith&Itemid=53 HTTP/1.1" 200 32653 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)" "-"
157.48.153.185 - - [19/Dec/2020:14:08:06 +0100] "GET /apache-log/access.log HTTP/1.1" 200 233 "-" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-"
157.48.153.185 - - [19/Dec/2020:14:08:08 +0100] "GET /favicon.ico HTTP/1.1" 404 217 "http://www.almhuette-raith.at/apache-log/access.log" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-"
216.244.66.230 - - [19/Dec/2020:14:14:26 +0100] "GET /robots.txt HTTP/1.1" 200 304 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, [email protected])" "-"
54.36.148.92 - - [19/Dec/2020:14:16:44 +0100] "GET /index.php?option=com_phocagallery&view=category&id=2%3Awinterfotos&Itemid=53 HTTP/1.1" 200 30662 "-" "Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)" "-"
92.101.35.224 - - [19/Dec/2020:14:29:21 +0100] "GET /administrator/index.php HTTP/1.1" 200 4263 "" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)" "-"
73.166.162.225 - - [19/Dec/2020:14:58:59 +0100] "GET /apache-log/access.log HTTP/1.1" 200 1299 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Safari/537.36" "-"

上記の各行は、この形式のさまざまなエントリを表しています。

IP-ADDRESS - - [TIMESTAMP] REQUEST & REQUEST-INFORMATION

次のセクションでは、このファイルからIPアドレスを抽出するためのさまざまな方法について説明します。

3. grepを使用する

Linux grepコマンドは、1つまたは複数のファイル内の特定の文字列を検索するための最も強力なユーティリティの1つです。大きなアクセスログファイルを検索する必要がある状況で非常に役立ちます。

IPアドレスの形式に一致する正規表現パターンを作成して使用します。

$ grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' sample.log
13.66.139.0
157.48.153.185
157.48.153.185
216.244.66.230
54.36.148.92
92.101.35.224
73.166.162.225

上記のコマンドでは、それぞれがドットで区切られた4つの同一部分を持つ正規表現があります。 各正規表現は、0から9の範囲の1から3桁を表します。

デフォルトでは、 grep コマンドは、一致するパターンを含む行全体を出力します。 -o オプションを使用して結果をトリミングし、一致した部分のみを印刷しました。

上記の通常の式には、有効なIPv4アドレスの範囲外のIPアドレスにも一致する可能性があるため、欠陥があります。 入力ファイルに有効なIPv4アドレスのみが含まれていることが確実な場合にのみ使用できます。

3.1. 有効なIPv4アドレスのみを抽出する

さらに厳密にするために、有効なIPv4アドレスのみに一致するように正規表現を変更してみましょう。

これを効果的にテストするために、“ 999.888.777.666”などのIPアドレスをsample.logファイルの最後に追加しましょう。

$ echo "999.888.777.666" >> sample.log

これにより、ファイルの最後に無効なIPアドレスが追加されます。

次に、正規表現を変更して、grepを再度実行できます。

$ grep -Eo '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' sample.log
13.66.139.0
157.48.153.185
157.48.153.185
216.244.66.230
54.36.148.92
92.101.35.224
73.166.162.225

この正規表現は、4つの部分のそれぞれで255以下の値を持つIPアドレスにのみ一致するため、より厳密です。

-E オプションを使用してパターンを拡張正規表現(ERE)として解釈し、 -o オプションを使用して結果をトリミングし、一致した部分のみを印刷します。

さらにプッシュして、結果をuniqおよびsortコマンドにパイプすることができます。 これにより、レコードがカウントされ、昇順で並べ替えられます。 また、リストをフィルタリングして、一意のIPアドレスとそれぞれのカウントのみを出力するようにします。

$ grep -Eo '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' sample.log | uniq -c | sort
      1 13.66.139.0
      1 216.244.66.230
      1 54.36.148.92
      1 92.101.35.224
      1 73.166.162.225
      2 157.48.153.185

-cオプションをuniqコマンドに渡して、個々のIPアドレスの総数を取得します。

4. Perlの使用

PerlはPracticalExtractionandReportLanguageの略です。 ファイルまたはstdinを介して入力されたデータに基づいてレポートを印刷する場合に便利です。 クイックワンライナーから本格的なアプリケーションまで、プログラムの作成に使用される汎用言語に成長しました。

Perlを使用して、以前と同じ正規表現を使用して有効なIPアドレスを抽出できます。

$ perl -nle '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/ and print $&' sample.log
13.66.139
157.48.153
157.48.153
216.244.66
54.36.148
92.101.35
73.166.162

-n オプションを使用して、-eオプションによって実行されるコードにループを追加しています。 -l オプションは、すべてのレコードがその行に印刷されることを保証し、読みやすさを向上させます。

また、Perlコマンドでパイプを使用して各IPアドレスの総数を取得し、結果を昇順または降順で並べ替えることもできます。

$ perl -nle '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/ and print $&' sample.log | uniq -c | sort
      1 13.66.139.0
      1 216.244.66.230
      ...truncated...

出力リダイレクト( >> )オプションを使用し、出力ファイルを指定することで、結果を出力ファイルに保存することもできます。

$ perl -nle '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/ and print $&' sample.log >> output_file.txt

5. awkを使用する

awkコマンドは、データを操作し、データに基づいてレポートを生成するLinuxユーティリティです。検索するテキストパターンを定義するステートメントとして、小さいながらも効果的なプログラムを記述できます。 さらに、一致が見つかったときに実行するアクションを定義できます。

awk コマンドを使用して、sample.logファイルからすべてのIPアドレスを抽出する方法を見てみましょう。

$ awk 'match($0, /(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/) {print substr($0, RSTART, RLENGTH)}' sample.log
13.66.139
157.48.153
157.48.153
216.244.66
54.36.148
92.101.35
73.166.162

match()関数を使用して、文字列と正規表現を定義しています。 次に、文字列( $ 0 )と、事前定義された変数RSTARTおよびRLENGTHを含む部分文字列を出力します。 これらの変数は、一致した文字列の文字のインデックスと長さを表します。

または、 sample.log ファイルと同じ形式の有効なアクセスログファイルからIPアドレスのリストを取得する場合は、awkを使用して最初のアドレスを取得できます。桁:

$ awk '{print $1}' sample.log 
13.66.139.0
157.48.153.185
157.48.153.185
216.244.66.230
54.36.148.92
92.101.35.224
73.166.162.225

最初の列は通常、ほとんどのアクセスログファイルのIPアドレスです。

6. 結論

この記事では、入力ファイルからIPv4アドレスを抽出するさまざまな方法について説明しました。 メソッドは互いに似ていますが、コア部分は定義する正規表現です。

各IPv4アドレスとその詳細を詳しく調べたい場合は、-oオプションなしでgrepコマンドを使用できます。 ただし、IPアドレスのリストを取得したいだけの場合は、これまでに説明した他の方法でも機能します。