Řekněme, že mám velký textový soubor (>2 GB) a chci jen cat
řádky X
na Y
(např. 57890000 až 57890010).
Z toho, co jsem pochopil, to mohu udělat pomocí potrubí head
do tail
nebo naopak, tj.
head -A /path/to/file | tail -B
nebo alternativně
tail -C /path/to/file | head -D
kde A
,B
,C
a D
lze vypočítat z počtu řádků v souboru X
a Y
.
Tento přístup má ale dva problémy:
- Musíte vypočítat
A
,B
,C
aD
. - Příkazy by mohly
pipe
navzájem mnoho dalších řádků, než mám zájem číst (např. když čtu jen pár řádků uprostřed velkého souboru)
Existuje způsob, jak zajistit, aby shell pracoval a vydával řádky, které chci? (a přitom poskytuje pouze X
a Y
)?
Přijatá odpověď:
Doporučuji sed
řešení, ale pro úplnost,
awk 'NR >= 57890000 && NR <= 57890010' /path/to/file
Pro vyříznutí za posledním řádkem:
awk 'NR < 57890000 { next } { print } NR == 57890010 { exit }' /path/to/file
Test rychlosti (zde na macOS, YMMV na jiných systémech):
- 100 000 000řádkový soubor vygenerovaný
seq 100000000 > test.in
- Čtení řádků 50 000 000–50 000 010
- Testy v žádném konkrétním pořadí
real
čas podlebash
vestavěný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
V žádném případě se nejedná o přesná měřítka, ale rozdíl je dostatečně jasný a opakovatelný* na to, aby poskytl dobrý pocit relativní rychlosti každého z těchto příkazů.
*:S výjimkou mezi prvními dvěma, sed -n p;q
a head|tail
, které se zdají být v podstatě stejné.