232

サーバーの問題をデバッグしようとしていますが、私の唯一のログ ファイルは 20 GB のログ ファイルです (タイムスタンプさえありません! なぜ人々はSystem.out.println()ログとして使用するのですか? 本番環境で?!)

grep を使用して、347340107 行目で確認したいファイルの領域を見つけました。

のようなことをする以外に

head -<$LINENUM + 10> filename | tail -20 

...ログ ファイルの最初の 3 億 4,700 万行を読み取る必要がheadありますが、347340100 ~ 347340200 行 (たとえば) をコンソールにダンプする、すばやく簡単なコマンドはありますか?

更新grep が一致の前後のコンテキストを出力できることを完全に忘れていました...これはうまく機能します。ありがとう!

4

18 に答える 18

433

行番号がわかっているが他に何もない場合(grepは不可能)、他に2つの解決策を見つけました。

20行目から40行目が必要だとすると、

sed -n '20,40p;41q' file_name

また

awk 'FNR>=20 && FNR<=40' file_name

使用する場合sedは、ファイルの最後まで処理を続けるよりも、最後の行を出力してから処理を終了する方が効率的です。これは、大きなファイルや最初に行を印刷する場合に特に重要です。そうするために、sed上記のコマンドは、41 行目以降の処理を停止する命令を導入します41q。この例では、20 ~ 40 行のみに関心があるためです。41 を、関心のある最後の行に 1 を加えたものに変更する必要があります。

于 2008-10-10T14:06:32.503 に答える
67

GNU-grep を使用すると、次のように言うことができます

grep --context=10 ...
于 2008-10-10T13:55:48.453 に答える
25

いいえ、ファイルは行アドレス指定可能ではありません。

テキスト ファイルの行nの開始を一定時間で見つける方法はありません。ファイルをストリーミングし、改行をカウントする必要があります。

仕事をするために必要な最も簡単で最速のツールを使用してください。私にとっては、 を使用headする方が よりもはるかに理にかなっていgrepます。後者ははるかに複雑だからです。「遅い」と言っているわけではありませんが、実際にはそうではありませんが、この場合grepよりも速い場合は驚くでしょう. 基本的headに、それは のバグです。head

于 2008-10-15T13:55:17.187 に答える
22

どうですか:

tail -n +347340107 filename | head -n 100

私はそれをテストしませんでしたが、うまくいくと思います。

于 2008-10-10T13:58:23.067 に答える
12

最初に、ファイルをこのようないくつかの小さなファイルに分割します

$ split --lines=50000 /path/to/large/file /path/to/output/file/prefix

結果のファイルをgrepします。

于 2008-10-10T15:13:25.003 に答える
4

sed は、行数をカウントするためにデータも読み取る必要があります。ショートカットが可能な唯一の方法は、操作するファイルにコンテキスト/順序があることです。たとえば、ログ行の先頭に固定幅の時刻/日付などが追加されている場合、look unix ユーティリティを使用して、特定の日付/時刻のファイルをバイナリ検索できます。

于 2013-08-07T01:01:40.890 に答える
2

N+1 から M までの行を印刷しsed -e '1,N d; M q'ます。これは、grep -C行をパターンに一致させようとしないため、おそらく多少は改善されます。

于 2008-10-10T14:05:10.993 に答える
1

から行を表示するには<textfile><line#>次のようにします。

perl -wne 'print if $. == <line#>' <textfile>

正規表現を使用して行の範囲を表示するより強力な方法が必要な場合-これを行うのにgrepが悪い考えである理由は言いませんが、かなり明白なはずです-この単純な式は範囲を表示します〜20GBのテキストファイルを扱うときに必要なシングルパス:

perl -wne 'print if m/<regex1>/ .. m/<regex2>/' <filename>

(ヒント: 正規表現が含まれている場合は、代わりに/次のようなものを使用してください)m!<regex>!

これは、一致する行から<filename>始まり、一致<regex1>する行まで (およびそれを含む) を出力し<regex2>ます。

いくつかの調整でさらに強力になる方法を理解するのに、魔法使いは必要ありません。

最後に: perl は成熟した言語であるため、速度とパフォーマンスを向上させるための多くの隠れた拡張機能があります。これを念頭に置いて、もともと大きなログファイル、テキスト、データベースなどを処理するために開発されたので、このような操作には当然の選択です。

于 2015-02-07T14:26:58.700 に答える
0

パールで簡単!ファイルから 1 行目、3 行目、5 行目を取得する場合は、/etc/passwd とします。

perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
于 2016-03-23T13:37:41.983 に答える
0

このコマンドを試すことができます:

egrep -n "*" <filename> | egrep "<line number>"
于 2015-10-22T03:26:29.623 に答える
0

出力に行番号を追加するよう提案された他の回答 (Ramana Reddy によるもの) が 1 つしかないことに驚いています。以下は、必要な行番号を検索し、出力に色を付けます。

file=FILE
lineno=LINENO
wb="107"; bf="30;1"; rb="101"; yb="103"
cat -n ${file} | { GREP_COLORS="se=${wb};${bf}:cx=${wb};${bf}:ms=${rb};${bf}:sl=${yb};${bf}" grep --color -C 10 "^[[:space:]]\\+${lineno}[[:space:]]"; }
于 2018-02-09T15:50:53.243 に答える