web-dev-qa-db-ja.com

ファイルの途中に特定の行を表示するためのクイックUNIXコマンド?

サーバーと私の唯一のログファイルの問題をデバッグしようとしているのは20GBのログファイルです(タイムスタンプもありません!なぜ人々はロギングとしてSystem.out.println()を使うのですか?プロダクション?)

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

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

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

...これは、ログファイルの最初の3億4,700万行を読み取るためにheadが必要になる場合がありますが、347340100〜347340200行をコンソールにダンプする迅速で簡単なコマンドはありますか。

pdate私はgrepがマッチの周りのコンテキストを表示できることを完全に忘れていました...これはうまくいきます。ありがとうございます。

178
matt b

gNU-grepでは、あなたはただ言うことができます

grep --context = 10 ...
68
Mathias Weidner

私はあなたが行番号を知っているが他には何も知らないのであれば、私は他に2つの 解決策 を見つけた。

20行目から40行目が必要だとします。

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

または

awk 'FNR>=20 && FNR<=40' file_name
357
Sklivvz
# print line number 52
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3,  efficient on large files 

大きなファイルでは方法3が効率的

特定の行を表示するための最速の方法

101
WCC

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

テキストファイル内で行の先頭nを見つけるための定時的な方法はありません。ファイルをストリーミングして改行を数える必要があります。

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

23
unwind

どうですか?

tail -n +347340107 filename | head -n 100

テストはしていませんが、うまくいくと思います。

19
itsmatt

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

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

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

12
Luka Marinko

私はちょうどlessに入ることを好みます

  • タイピング 5% ファイルの途中まで移動する
  • 43210G 43210行目に移動する
  • 同じことをする:43210

そしてそのようなもの。

さらに良い:ヒット v その場所で(もちろん、vimで)編集を開始します。さて、vimは同じキー割り当てを持っていることに注意してください。

11
sehe

あなたは 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!)。
8
kenorb

気をつけろ

ack --lines =開始 - 終了ファイル名

5
Odeyin

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

4
pixelbeat

つかいます

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>
3
Ramana Reddy

あなたの行番号が読むために100であるなら

head -100 filename | tail -1
3
Roopa

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
}
2
Keithel

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

2
mweerden

<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は成熟した言語であるため、速度とパフォーマンスを向上させるために多くの隠された機能強化が行われています。これを念頭に置いて、それはもともと大きなログファイル、テキスト、データベースなどを処理するために開発されたのでそれはそのような操作のための明らかな選択になります。

1
osirisgothra

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

Perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
0
dagelf

あなたはこのコマンドを試すことができます:

egrep -n "*" <filename> | egrep "<line number>"
0
Fritz Dodoo

出力に行番号を追加するように提案された(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:]]"; }
0
eel ghEEz