Podziel plik na dwa pliki w danym wierszu

12

Szukam sposobu w unixie, aby podzielić plik na dwa pliki pod danym numerem linii.

split -l 100 file_namejest zbliżony do tego, czego szukam, ale to polecenie tworzy wiele plików, każdy po 100 wierszy. Szukam polecenia, aby podzielić plik na dwa pliki pod danym numerem wiersza. Czy jest na to sposób w Unixie?

żółw
źródło

Odpowiedzi:

13

Nieco ściślejsze rozwiązanie:

(head -100 > f1.txt; cat > f2.txt) < input.txt
Rubens
źródło
1
Niezłe rozwiązanie. Nie licząc wcwcześniej, a plik wejściowy jest przetwarzany tylko raz, podobnie jak w przypadku awkrozwiązania.
Dubu,
2
Istnieje niewielka szansa, że headprzeczyta więcej niż 100 linii w celu znalezienia pierwszych 100 linii do wysłania f1.txt; te dodatkowe bajty nie będą widoczne przez cat.
chepner
To jest cholernie wolne
sdaffa23fdsf
12

Użyj awk, aby wykonać tylko jedno przejście przez plik wejściowy. Poniżej założono, że chcesz pierwsze 122 wiersze w pierwszym pliku, a pozostałe w drugim.

awk 'NR < 123 { print >> "top_file"; next } {print >> "bottom_file" }' file_name
chepner
źródło
To zasługuje na kciuki do góry. jeśli chcesz podzielić plik z X na Y, jest to najłatwiejsze.
Glenn Plas
To najłatwiejsze do zrozumienia rozwiązanie. Działał jak urok ... i sprawia, że ​​myślę, że powinienem otrzepać kurz z mojej książki O'Reilly Sed & Awk, którą miałem od około 1999 roku, sekcja sed jest dobrze przeczytana, sekcja awk nie tyle.
Michael
Jest to lepsze niż wyjątek z powodu podanego w komentarzach @chepner. Utracisz znaki w pliku „f2.txt”. To rozwiązanie jest dokładne i wydajne. awk ftw.
Goran,
7

Możesz użyć headi, tailaby uzyskać obie części:

head -n K file_name > top_file
tail -n L file_name > bottom_file

gdzie Kjest numerem linii i Ljest liczbą linii od dołu (całkowita liczba linii - K).

(możesz uzyskać łączną liczbę linii za pomocą wc -l file_name).

jh314
źródło
5

Możesz to zrobić csplit(jeśli jest dostępne):

csplit file N+1

podzieli plik na dwie części, jedną do numeru linii (włącznie) Ni drugą od numeru linii N+1do ostatniej linii.
Jeśli chcesz podzielić numer linii (ale nie w tym) N:

csplit file N
don_crissti
źródło
To wspaniale! Dzięki, rozwiązałem problem idealnie dla mnie.
Zertrin
Najlepsza wydajność dzielenia pliku 20 GB na części.
dr0i
@ dr0i - nic dziwnego, csplitjest zoptymalizowany do tego zadania.
don_crissti
Dzieląc plik o długości 200 milionów wierszy „wyczerpałem pamięć”, używając csplit datowanego na 2008 rok. Używając csplit datowanego na 2011 rok działa :)
dr0i
4

Zarówno headi tailmają opcje do linii produktów z „innej” koniec pliku, niż byłoby inaczej. Masz więc dwie opcje:

head -n 100 source.txt > file1.txt
head -n -100 source.txt > file2.txt

lub (gdzie NNN jest o 100 mniejszy niż wynik wc -l source.txt):

tail -n +NNN source.txt > file1.txt
tail -n NNN source.txt > file.txt

Możesz przeczytać strony podręcznika dla swoich wersji headi tailuzyskać więcej informacji.

twalberg
źródło
0

Możesz użyć „wc”, „dc”, „head” i „tail”. To znaczy

unix> wc -l foo
545 /tmp/foo
unix> dc -e '545 100 - p'
445
unix> head -n 100 foo > filea
unix> tail -n 445 foo > fileb

Aby ułatwić obsługę, możesz zmienić powyższy skrypt w skrypt powłoki.


źródło