Linuxの便利なcmd行ユーティリティhead
とtail
は誰もが知っていると思います。 head
を使用すると、ファイルの最初のX行を印刷できます。tail
も同じことを行いますが、ファイルの最後を印刷します。ファイルの途中を印刷するのに適したコマンドは何ですか?何かのようなもの middle --start 10000000 --count 20
(10000'000番目から10000'010番目の行までを印刷します)。
大きなファイルを効率的に処理できるものを探しています。私は試した tail -n 10000000 | head 10
そしてそれは恐ろしく遅いです。
sed -n '10000000,10000020p' filename
あなたはこれを少しこのようにスピードアップできるかもしれません:
sed -n '10000000,10000020p; 10000021q' filename
これらのコマンドでは、オプション-n
により、sed
が「パターンスペースの自動印刷を抑制」します。 p
コマンド「現在のパターンスペースを印刷[s]」およびq
コマンド「これ以上入力を処理せずにsedスクリプトをすぐに終了[s] ...」引用符は sed
man
page 。
ちなみに、あなたのコマンド
tail -n 10000000 filename | head 10
ファイルのendから1000万行目から始まりますが、「middle」コマンドはbeginningこれは以下と同等です。
head -n 10000010 filename | tail 10
問題は、可変長行を含むソートされていないファイルの場合、プロセスは改行をカウントしてファイルを通過する必要があることです。それをショートカットする方法はありません。
ただし、ファイルがソートされている場合(タイムスタンプが含まれているログファイルなど)、または固定長の行がある場合は、バイト位置に基づいてファイルをシークできます。ログファイルの例では、my Python script here *の場合と同様に、ある範囲のバイナリ検索を実行できます。固定レコード長のファイルの場合、それは本当に簡単です。ファイルにlinelength * linecount
文字をシークするだけです。
*そのスクリプトにさらに別の更新を投稿するつもりです。たぶん、いつの日かそれを回避するでしょう。
sed
の次の使用法を見つけました
sed -n '10000000,+20p' filename
それが誰かに役立つことを願っています!
初めての投稿です!とにかく、これは簡単です。 file.txtというファイルから8872行目を取得するとします。方法は次のとおりです。
cat -n file.txt | grep '^ * 8872'
ここで問題は、この後20行を見つけることです。これを達成するには
cat -n file.txt | grep -A 20 '^ * 8872'
前後の行については、grepマニュアルの-Bおよび-Cフラグを参照してください。
次のコマンドを使用して、特定の範囲の行を取得します。
awk 'NR < 1220974{next}1;NR==1513793{exit}' debug.log | tee -a test.log
ここで、debug.logは、欠落した行で構成されるファイルであり、1220974行番号から1513793までの行をファイルtest.logに出力するために使用しました。ラインの範囲をキャプチャするのに役立つことを願っています。
デニスのsedの答えは行く方法です。しかし、頭と尾だけを使用して、bashの下で:
中央(){頭-n $ [$ 1 + $ 2] |尾-n $ 2; }
これは最初の$ 1 + $ 2行を2回スキャンするため、Dennisの回答よりもはるかに悪いです。しかし、それを使用するためにこれらすべてのsed文字を覚えておく必要はありません。
A Rubyワンライナーバージョン。
Ruby -pe 'next unless $. > 10000000 && $. < 10000020' < filename.txt
それは誰かに役立つことができます。 DennisとDoxが提供する「sed」を使用したソリューションは非常に高速です。
Perlが王様です:
Perl -ne 'print if ($. == 10000000 .. $. == 10000020)' filename
行番号がわかっている場合は、ファイルから1行目、3行目、5行目を取得する場合は、/ etc/passwdと指定します。
Perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
「nl」を使用できます。
nl filename | grep <line_num>
たとえば、このawkは20〜40の行を印刷します
awk '{if((NR> 20)&&(NR <40))print $ 0}'/etc/passwd