サーバーと私の唯一のログファイルの問題をデバッグしようとしているのは20GBのログファイルです(タイムスタンプもありません!なぜ人々はロギングとしてSystem.out.println()
を使うのですか?プロダクション?)
Grepを使用して、347340107行目で見たいファイルの領域を見つけました。
のようなことをすること以外
head -<$LINENUM + 10> filename | tail -20
...これは、ログファイルの最初の3億4,700万行を読み取るためにhead
が必要になる場合がありますが、347340100〜347340200行をコンソールにダンプする迅速で簡単なコマンドはありますか。
pdate私はgrepがマッチの周りのコンテキストを表示できることを完全に忘れていました...これはうまくいきます。ありがとうございます。
gNU-grepでは、あなたはただ言うことができます
grep --context = 10 ...
私はあなたが行番号を知っているが他には何も知らないのであれば、私は他に2つの 解決策 を見つけた。
20行目から40行目が必要だとします。
sed -n '20,40p;41q' file_name
または
awk 'FNR>=20 && FNR<=40' file_name
# print line number 52
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3, efficient on large files
大きなファイルでは方法3が効率的
特定の行を表示するための最速の方法
ありません、ファイルは行アドレス指定できません。
テキストファイル内で行の先頭nを見つけるための定時的な方法はありません。ファイルをストリーミングして改行を数える必要があります。
あなたが仕事をしなければならない最も簡単で最速のツールを使ってください。私にとっては、head
を使用するとgrep
よりもはるかの方が理にかなっています。私は「grep
が遅い」と言っているわけではありませんが、実際はそうではありませんが、この場合、head
より速い場合は驚きます。これは基本的にhead
のバグです。
どうですか?
tail -n +347340107 filename | head -n 100
テストはしていませんが、うまくいくと思います。
私は最初にこのようないくつかの小さいファイルにファイルを分割します
$ split --lines=50000 /path/to/large/file /path/to/output/file/prefix
そして結果のファイルをgrepします。
私はちょうどless
に入ることを好みます
:43210
そしてそのようなもの。
さらに良い:ヒット v その場所で(もちろん、vimで)編集を開始します。さて、vim
は同じキー割り当てを持っていることに注意してください。
あなたは ex
コマンドを使うことができます。これは標準のUnixエディタです(Vimの一部です)。
単一行(2行目など)を表示します。
ex +2p -scq file.txt
対応するsed構文:sed -n '2p' file.txt
行の範囲(2〜5行など)
ex +2,5p -scq file.txt
sed構文:sed -n '2,5p' file.txt
与えられた行から最後まで(例えば、ファイルの5番目から最後まで):
ex +5,p -scq file.txt
sed構文:sed -n '2,$p' file.txt
複数行の範囲(例:2-4行と6-8行)
ex +2,4p +6,8p -scq file.txt
sed構文:sed -n '2,4p;6,8p' file.txt
上記のコマンドは、次のテストファイルでテストできます。
seq 1 20 > file.txt
説明:
+
または-c
の後にコマンド - ファイルが読み込まれた後に(vi/vim)コマンドを実行します。-s
- サイレントモード。デフォルトの出力として現在の端末も使用します。q
に続けて-c
はエディタを終了するコマンドです(強制終了するには!
を追加してください、例えば-scq!
)。気をつけろ
ack --lines =開始 - 終了ファイル名
行数を数えるにはsedもデータを読み取る必要があります。ショートカットが可能になる唯一の方法は、操作するファイルにコンテキスト/順序があることです。たとえば、固定幅の時間/日付などが先頭に付いたログ行がある場合は、look unixユーティリティを使用して特定の日付/時間のファイルをバイナリ検索できます。
つかいます
x=`cat -n <file> | grep <match> | awk '{print $1}'`
ここでは、一致が発生した行番号を取得します。
今、あなたは100行を印刷するために次のコマンドを使うことができます
awk -v var="$x" 'NR>=var && NR<=var+100{print}' <file>
または、 "sed"も使えます
sed -n "${x},${x+100}p" <file>
あなたの行番号が読むために100であるなら
head -100 filename | tail -1
Sklivvzの答えに基づいて、これは.bash_aliases
ファイルに入れることができるNice関数です。ファイルの先頭からものを印刷するとき、それは大きなファイルで効率的です。
function middle()
{
startidx=$1
len=$2
endidx=$(($startidx+$len))
filename=$3
awk "FNR>=${startidx} && FNR<=${endidx} { print NR\" \"\$0 }; FNR>${endidx} { print \"END HERE\"; exit }" $filename
}
sed -e '1,N d; M q'
を使用すると、N + 1からMまでの行を印刷できます。これは、行をパターンに一致させようとしないため、おそらくgrep -C
より少し優れています。
<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は成熟した言語であるため、速度とパフォーマンスを向上させるために多くの隠された機能強化が行われています。これを念頭に置いて、それはもともと大きなログファイル、テキスト、データベースなどを処理するために開発されたのでそれはそのような操作のための明らかな選択になります。
Perlで簡単!ファイルから1行目、3行目、5行目を取得したい場合は、/ etc/passwdとします。
Perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
あなたはこのコマンドを試すことができます:
egrep -n "*" <filename> | egrep "<line number>"
出力に行番号を追加するように提案された(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:]]"; }