巨大なテキストファイル(> 2GB)があり、cat
したいだけだとします。 行X
Y
へ (例:57890000から57890010)。
私が理解していることから、head
を配管することでこれを行うことができます tail
に またはその逆、つまり
head -A /path/to/file | tail -B
または代わりに
tail -C /path/to/file | head -D
ここで、A
、B
、C
およびD
ファイルの行数X
から計算できます およびY
。
ただし、このアプローチには2つの問題があります。
-
A
を計算する必要があります 、B
、C
およびD
。 - コマンドは
pipe
お互いにもっとたくさん 読みたい行よりも多い行(たとえば、巨大なファイルの途中で数行だけ読んでいる場合)
シェルを操作して、必要な行を出力する方法はありますか? (X
のみを提供します およびY
)?
承認された回答:
sed
をお勧めします 解決策ですが、完全を期すために
awk 'NR >= 57890000 && NR <= 57890010' /path/to/file
最後の行の後に切り取るには:
awk 'NR < 57890000 { next } { print } NR == 57890010 { exit }' /path/to/file
速度テスト(ここではmacOS、他のシステムではYMMV):
- 100,000,000-
seq 100000000 > test.in
によって生成された行ファイル - 50,000,000〜50,000,010行の読み取り
- 順不同でテスト
real
bash
によって報告された時間 の組み込みのtime
4.373 4.418 4.395 tail -n+50000000 test.in | head -n10
5.210 5.179 6.181 sed -n '50000000,50000010p;57890010q' test.in
5.525 5.475 5.488 head -n50000010 test.in | tail -n10
8.497 8.352 8.438 sed -n '50000000,50000010p' test.in
22.826 23.154 23.195 tail -n50000001 test.in | head -n10
25.694 25.908 27.638 ed -s test.in <<<"50000000,50000010p"
31.348 28.140 30.574 awk 'NR<57890000{next}1;NR==57890010{exit}' test.in
51.359 50.919 51.127 awk 'NR >= 57890000 && NR <= 57890010' test.in
これらは決して正確なベンチマークではありませんが、これらの各コマンドの相対速度を十分に理解できるように、違いは明確で再現性があります*。
*:最初の2つを除いて、sed -n p;q
およびhead|tail
、これは本質的に同じようです。