切り取りコマンドを組み合わせてカスタム区切り文字を使用できますか?

切り取りコマンドを組み合わせてカスタム区切り文字を使用できますか?

ログファイルがあり、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 ここ

cut1+ で例を使用すると、次のように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 thiswith this)に置き換えられることを示します。最初の置換コマンドは何もsed変更しないように指示し/、2番目のコマンドは$行末()をに "置き換えます" ,。以下についてもっと読むことができます。sed ここ。また、私がgrepこれを行っていることに注意してください" 404。これは少しハッキーですが、他のgrep場所に表示される行(ファイル名、ファイルサイズ、日付など)については404を返しません。

使用perl:

grep '" 404' testfile.txt | perl -lane 'print substr($F[6],1).","'

これは例と似ていますが、入力をフィルタリングするawkためにも使用されます。grep同じアイデアを使用して、awk7番目substr($F[6],1)のフィールド()の部分文字列を印刷し、.","出力にコンマ()を追加します。 Perlは0から計算を開始し、awkは1から計算を開始するため、awkでasを使用してinを使用して7番目のフィールドを$F[6]取得します。指示を見つけることができますperl$7perlここ

答え2

区切り文字スペース( )を使用してフィルタリングしてみましたか?

awk '$9=="404" {print $7}' testfile.txt|sort -u

または以下を使用してください。

grep 404 testfile.txt | cut -f 7 -d ' '|sort -u

PSたとえば、ダウンロードの長さが404バイトの場合、2番目の方法が一致します。または、年に404文字列が含まれています。または、要求されたURLにこの文字列が含まれています。

答え3

使用awkコマンド:

awk -F '[ /]' '/ 404 / {print $10|"sort -u"}' testfile.txt

説明する:

  • -F '[ /]':スペース ""とスラッシュ "/"を区切り文字として使用します。 (複数の区切り記号)
  • / 404 /:「404」を含む行だけが一致します。grep " 404 " testfile.txt仕事と同じです。

ノート:「404」の前後に多少のスペースがあります。

これにより、レスポンスコードではなくURLに表示される可能性がある誤った肯定一致が削除されます。たとえば、次の行は一致しません。

ip - - [12/Dec/2019:13:18:00 +0000] "GET /test404.html HTTP/1.1" 200 710 "-" "python-requests/2.18.4"

ノート:test404.htmlURLに次のものが含まれています404しかし、レスポンスコードは200。したがって、「404」の前後にスペースが必要です。

  • print $10:10番目のフィールドを表示するには、スペースとスラッシュを区切り文字として使用します。
  • | sort -u : 結果をソートし、重複インスタンスを 1 つだけ取得します。 (つまり、行のみを表示)
  • testfile.txt:一致させる行を含むファイル。

ノート: 別の行があるが404興味がないと仮定すると、次のように一致を絞り込むことができます。

awk -F '[ /]' '/GET.* 404 / {print $10|"sort -u"}' testfile.txt

修正内容:

  • /GET.* 404 /GET:「次に他のものが続き、次に」が含まれている404行のみが一致します。

ついに:

  • URLの前にスラッシュを追加するには、次のようにします。

    awk '/ 404 / {print $7|"sort -u"}' testfile.txt
    
  • URLの後にカンマを追加するには、次のようにします。

    awk -F '[ /]' '/ 404 / {print $10","|"sort -u"}' testfile.txt
    
  • URLの前にスラッシュを追加し、URLの後にコンマを追加するには、次のようにします。

    awk '/ 404 / {print $7","|"sort -u"}' testfile.txt
    

関連情報