Podziel plik na dwie części

18

Mam duży plik i muszę podzielić na dwa pliki. Załóżmy, że w pierwszym pliku należy wybrać 1000 linii i umieścić je w innym pliku oraz usunąć te linie w pierwszym pliku.

Próbowałem użyć, splitale tworzy wiele fragmentów.

Aravind
źródło
Sprawdziłeś split --help?
Braiam
Tak, sprawdziłem to, ale tworzę wiele plików, które mnie nie potrzebują.
Aravind

Odpowiedzi:

31

Najłatwiejszym sposobem jest prawdopodobnie użycie headi tail:

$ head -n 1000 input-file > output1
$ tail -n +1001 input-file > output2

Że wprowadzi pierwsze 1000 wierszy z input-fileINTO output1oraz wszystkie linie od 1001 do końca woutput2

Michał Mrożek
źródło
13

Myślę, że splitto najlepsze podejście.

Spróbuj użyć -l xxxxopcji, gdzie xxxx to liczba linii, które chcesz w każdym pliku (domyślnie jest to 1000).

Możesz użyć tej -n yyopcji, jeśli bardziej martwi Cię liczba utworzonych plików. Użyj -n 2podzieli twój plik na tylko 2 części, bez względu na ilość linii w każdym pliku.

Możesz policzyć liczbę linii w swoim pliku wc -l filename. Jest to polecenie „wordcount” z opcją linii.

Bibliografia

  • man split
  • man wc
Lucien Raven
źródło
1
Oto jak podzielić na kilka plików ze stałą liczbą linii lub jak równomiernie podzielić na określoną liczbę plików. Czy istnieje sposób na podzielenie na jeden plik 1000-liniowy i jeden plik ze wszystkim innym? O to prosił; Nie mogłem go znaleźć na stronie podręcznika
Michael Mrozek
Masz rację, Michael. Myślę, że w uproszczony sposób zająłem się tym pytaniem. Twoje rozwiązanie jest najlepsze w tym przypadku. Innym sposobem może być użycie polecenia „sed”: sed -n 1,1000 originalfile> first_1000_lines. sed '1,1000d' oryginalny plik> pozostałe_wiersze.
Lucien Raven
Oczywiście, że możesz split -l 1000 bigfile && mv xaa piece1 && cat x?? > piece2 && rm x??.
G-Man mówi „Przywróć Monikę”
8

To jest praca dla csplit:

csplit -s infile 1001 

srozłoży się iluzorycznie infile, pierwszy kawałek xx00- do linii 1001, ale bez niej, a drugi kawałek xx01- pozostałe linie.
Możesz grać z opcjami, jeśli potrzebujesz różnych nazw plików wyjściowych, np. Używając -fi określając prefiks :

csplit -sf piece. infile 1001 

tworzy dwa pliki o nazwie piece.00ipiece.01


Za pomocą smarta headmożesz także zrobić coś takiego:

{ head -n 1000 > 1st.out; cat > 2nd.out; } < infile
don_crissti
źródło
1
Wow, to naprawdę jest to zadanie dla csplit. Bardzo dobrze. (Właśnie czytam listę poleceń POSIX i na początku miałem ogromne problemy z owinięciem głowy wokół celu csplitpolecenia. Okazuje się, że to naprawdę bardzo proste.) :)
Wildcard,
4

Prosty sposób na zrobienie tego, o co pyta jedno pytanie:

awk '{ if (NR <= 1000) print > "piece1"; else print > "piece2"; }' bigfile

lub dla tych z was, którzy naprawdę nie znoszą pisać długich, intuicyjnie zrozumiałych poleceń,

awk '{ print > ((NR <= 1000) ? "piece1" : "piece2"); }' bigfile
G-Man mówi „Przywróć Monikę”
źródło