テキストファイルからフラグメントをインポートする最良の方法は何ですか?

テキストファイルからフラグメントをインポートする最良の方法は何ですか?

巨大なテキストファイルから20〜45行を抽出する良い方法は何ですか?もちろん非対話型です!

答え1

より簡単です:

sed -n '20,45p;45q' < textfile

-n フラグはデフォルト出力をディセーブルにします。 「20,45」は、20行から45行(含む)のアドレスを指定します。 "p"コマンドは現在の行を印刷します。 qこの行を印刷して終了します。

答え2

あなたは試すことができます:

cat textfile | head -n 45 | tail -n 26

または

cat textfile | awk "20 <= NR && NR <= 45" 

修正する:

Mahomedalidが指摘したように、catこれは必須ではなく少し冗長ですが、きれいで読みやすいコマンドを作成します。

catそれがあなたを悩ませている場合、より良い解決策は次のとおりです。

<textfile awk "20 <= NR && NR <= 45"

答え3

答えではありませんが、コメントとして投稿することはできません。

別の(非常に速い)方法は次のとおりです。マックサイフ ここ:

{ head -n 19 >/dev/null; head -n 26; } <infile

同じテストファイルを使うここそして、同じプロセスのいくつかのベンチマークは次のとおりです(行1000020-1000045抽出)。

マックサイフ:

{ head -n 1000019 >/dev/null; head -n 26; } <iplist

real    0m0.059s

ステファン:

head iplist -n 1000045 | tail -n 26

real    0m0.054s

これはこれまで最速の解決策であり、違いは無視できます。(シングルパスの場合)(いくつかの行、何百万もの行など、さまざまな範囲を試しました。)

ただし、パイプラインを見つける必要があるアプリケーションの場合、パイプラインなしでこれを行うと、大きな利点が得られます。複数の範囲同様の方法で行を作成します。たとえば、次のようになります。

for  pass in 0 1 2 3 4 5 6 7 8 9
do   printf "pass#$pass:\t"
     head -n99 >&3; head -n1
done <<1000LINES 3>/dev/null
$(seq 1000)
1000LINES

...印刷...

pass#0: 100
pass#1: 200
pass#2: 300
pass#3: 400
pass#4: 500
pass#5: 600
pass#6: 700
pass#7: 800
pass#8: 900
pass#9: 1000

...ファイルを一度だけ読みます。


//他のsed解決策はファイル全体を読み込みますが、これは大容量ファイルに関するものであり、それほどawk効率perl的ではありません。指定された範囲の最後の行の後にいくつ exitかの選択肢を追加しました。q

ステファン:

awk "1000020 <= NR && NR <= 1000045" iplist

real    0m2.448s

そして

awk "NR >= 1000020;NR==1000045{exit}" iplist

real    0m0.243s

デカグダル( sed):

sed -n 1000020,1000045p iplist

real    0m0.947s

そして

sed '1,1000019d;1000045q' iplist

real    0m0.143s

スティーブンD:

perl -ne 'print if 1000020..1000045' iplist

real    0m2.041s

そして

perl -ne 'print if $. >= 1000020; exit if $. >= 1000045;' iplist

real    0m0.369s

答え4

sedとawkが採用されているので、以下はPerlソリューションです。

perl -nle "print if ($. > 19 && $. < 46)" < textfile

またはコメントで指摘したように:

perl -ne 'print if 20..45' textfile

関連情報