Katakanlah saya memiliki file teks besar (>2GB) dan saya hanya ingin cat
garis X
ke Y
(mis. 57890000 hingga 57890010).
Dari apa yang saya pahami, saya dapat melakukan ini dengan mem-pipe head
menjadi tail
atau sebaliknya, yaitu
head -A /path/to/file | tail -B
atau sebagai alternatif
tail -C /path/to/file | head -D
di mana A
,B
,C
dan D
dapat dihitung dari jumlah baris dalam file, X
dan Y
.
Tetapi ada dua masalah dengan pendekatan ini:
- Anda harus menghitung
A
,B
,C
danD
. - Perintah bisa
pipe
satu sama lain lebih banyak lagi baris daripada yang ingin saya baca (misalnya jika saya membaca hanya beberapa baris di tengah file besar)
Apakah ada cara agar Shell berfungsi dan menampilkan baris yang saya inginkan? (sambil memberikan hanya X
dan Y
)?
Jawaban yang Diterima:
Saya menyarankan sed
solusi, tetapi demi kelengkapan,
awk 'NR >= 57890000 && NR <= 57890010' /path/to/file
Untuk memotong setelah baris terakhir:
awk 'NR < 57890000 { next } { print } NR == 57890010 { exit }' /path/to/file
Tes kecepatan (di sini di macOS, YMMV di sistem lain):
- File 100,000,000-line dihasilkan oleh
seq 100000000 > test.in
- Baris bacaan 50.000.000-50.000.010
- Menguji tanpa urutan tertentu
real
waktu seperti yang dilaporkan olehbash
time
bawaan
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
Ini sama sekali bukan tolok ukur yang tepat, tetapi perbedaannya cukup jelas dan dapat diulang* untuk memberikan gambaran yang baik tentang kecepatan relatif dari masing-masing perintah ini.
*:Kecuali di antara dua yang pertama, sed -n p;q
dan head|tail
, yang tampaknya pada dasarnya sama.