ログファイルがあり、404dのGETリクエストからURLを抽出する必要があります。
私は以下を使用しました:
grep 404 testfile.txt | cut -f 2 -d '"' | cut -f 2 -d '/' | cut -f 1 -d ' ' | sort -u
このようにカットコマンドを一緒に入れることはお勧めできません。一行で合わせることができますか?たとえば、3番目の「/」と6番目の「」から切り抜き始めます。
ログファイルの例:
ip - - [12/Dec/2019:13:18:00 +0000] "GET /test.html HTTP/1.1" 200 710 "-" "python-requests/2.18.4"
ip - - [12/Dec/2019:13:18:00 +0000] "GET /403dz2.html HTTP/1.1" 404 492 "-" "python-requests/2.18.4"
結果:
403dz2.html,
is0pmq.html,
iw30ce.html,
nbk0px.html,
ベストアンサー1
以前のようにコマンドを一緒にパイピングすることには問題はありません。cut
ただし、大きな入力に対してこれを行うより効率的な方法がある可能性があることに注意してください。これは、あなたの例では、入力ファイルが端末に出力される前にコマンドとして5回処理される必要があるためです(grep
フィルタリングのために1回、別々のcut
解析コマンド3つ、解析のために1回sort
)。パイプを少なく使用可能パフォーマンスは向上しますが、これは最終的にコマンド自体と実行する操作によって異なります(つまり、3つの高速で簡単な作業が1つの大規模で計算集約的な作業よりも高速です)。入力データが比較的小さい場合は、パイプライン方式を使用するか、次のいずれかの方法を使用するかどうかに違いはありません。
メモ:次の例は、OPの元のコマンドチェーンと比較してどれだけ効率的か高速なのかわかりません。ユースケースに応じて、いくつかは他のものよりも「良い」かもしれません。
使用awk
: (尊重)
awk '$9=="404" {print substr($7,2)","}' testfile.txt
上記はRomeoの答えと似ていますが、ログ出力のファイル名から先行スラッシュを削除し、目的の結果に一致するようにコンマを末尾に追加します。awk
入力データを1行ずつ(デフォルトで)解析し、各行をスペース区切り(デフォルト)に分割するコマンド。このコマンドは9番目のフィールド(HTTPレスポンスコード)をチェックし、404
一致する場合は7番目のフィールドの部分文字列を2番目の文字から最後()まで取得し、substr($7,2)
そのフィールドの後にコンマ()を追加して出力を印刷します。","
以下についてもっと読むことができます。awk
ここ。
cut
1+ で例を使用すると、次のようにsed
なります。
grep '" 404' testfile.txt | cut -d' ' -f7 | sed 's/\///; s/$/,/'
ファイル名を抽出するには、3 つの個別の切り取りコマンドは必要なく、スペース区切り文字を使用する場合は 1 つだけが必要です。このcut
コマンドはロープを引き出します/403dz2.html
。これにより、sed
前のスラッシュ(s/\///
)が削除され、s/$/,/
最後にコンマ()が追加されます。何sed
ですか実際にここで実行される操作は代替です。文字列は、s/replace this/with this/
最初のsed
文字列()が2番目の文字列replace this
(with this
)に置き換えられることを示します。最初の置換コマンドは何もsed
変更しないように指示し/
、2番目のコマンドは$
行末()をに "置き換えます" ,
。以下についてもっと読むことができます。sed
ここ。また、私がgrep
これを行っていることに注意してください" 404
。これは少しハッキーですが、他のgrep
場所に表示される行(ファイル名、ファイルサイズ、日付など)については404を返しません。
使用perl
:
grep '" 404' testfile.txt | perl -lane 'print substr($F[6],1).","'
これは例と似ていますが、入力をフィルタリングするawk
ためにも使用されます。grep
同じアイデアを使用して、awk
7番目substr($F[6],1)
のフィールド()の部分文字列を印刷し、.","
出力にコンマ()を追加します。 Perlは0から計算を開始し、awkは1から計算を開始するため、awkでasを使用してinを使用して7番目のフィールドを$F[6]
取得します。指示を見つけることができますperl
$7
perl
ここ。