Podziel plik po linii i kontroluj wynikowe rozszerzenie plików


28

Istnieje standardowe polecenie dzielenia plików - split.

Na przykład, jeśli chcę podzielić plik słów na kilka fragmentów po 10000 linii, mogę użyć:

split -dl 10000 words wrd

i wygenerowałoby kilka plików w formie wrd.01, wrd.02 i tak dalej.

Ale chcę mieć specjalne rozszerzenie dla tych plików - na przykład chcę uzyskać pliki wtd.01.txt, wrd.02.txt.

Czy jest na to sposób?

Odpowiedzi:


12

Nie za pomocą split, ale możesz później łatwo zmienić ich nazwę lub możesz to zrobić w awk:

awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile

Wygląda dobrze - ale nie działa. W twoim formularzu skarży się na „wyrażenie na przekierowanie„ >> ”ma wartość pustego łańcucha”, a jeśli „plik” zostanie „zmieniony” na „nazwa pliku”, wyświetla pliki w postaci wrd. {Numer pliku}. {Numer linii} .txt (całkiem sporo :)
Rogach

@Rogach Przepraszam, nie testowałem tego, więc zapomniałem, że awk nie dzieli liczb całkowitych. Przetestowałem to.
Kevin

49

Nie było to wtedy dostępne, ale w nowszych wersjach ( ≥ 8.16) gnu splitmożna użyć --additional-suffixprzełącznika, aby mieć kontrolę nad wynikowym rozszerzeniem. Od man split:

--additional-suffix=SUFFIX
              append an additional SUFFIX to file names.

więc podczas korzystania z tej opcji:

split -dl 10000 --additional-suffix=.txt words wrd

powstałe elementy automatycznie kończą się na .txt:

wrd00.txt
wrd01.txt
.........

3
Nie działa na Mac
ericgu

2
Uwielbiam twój sarkazm. Jestem unix n00b ze świata Apple. Korzystam z systemu OS X Yosemite i po prostu nie chciałem, aby inni się zawieszali i palili tak jak ja. Przetestowałem i sprawdziłem w dokumentacji i nie mamy tego parametru. Mogłem coś przeoczyć. developer.apple.com/library/mac/documentation/Darwin/Reference/…
ericgu 10'15

5
@swiftshokunin - moja odpowiedź dotyczy gnu split, częściowo gnu coreutils. Jest również dostępny w OSX, jeśli instalujesz coreutilsprzez, homebrewale pamiętaj, że domyślnie w OSX gnunarzędzia mają gprzedrostek do swojej nazwy (np. gstatZamiast stat), więc możesz ją wywołać jako gsplit(lub zmienić PATH zgodnie z instrukcją tutaj, jeśli chcesz używać go tak jak splitw OSX split). HTH.
don_crissti

1
Niezła odpowiedź. w systemie OS X użyj, gsplitaby uruchomić przyrostki numeryczne (-d).
Brent Faust

1
wow, nie miałem pojęcia, że ​​istnieje gsplit - prawdopodobnie pochodzi z wymienionych wyżej rdzeni i ma - dodatkowy przyrostek. Dziękujemy wszystkim komentującym to rozwiązanie :)
Łukasz Rysiak

13

Takimi zadaniami najlepiej zarządzać za pomocą powłoki. Użyj podziału, a następnie napisz prostą pętlę, aby zmienić nazwę plików. Na przykład

for file in wrd.*
do
    mv "$file" "$file.txt"
done

zmieniłby nazwy plików wrd.01, wrd.02 itp., aby wszystkie miały rozszerzenie .txt.


To dość oczywiste, ale złamałoby to zwięzłość skryptu bash.
Rogach,

1
Filozofią Uniksa jest dostarczenie zestawu prostych narzędzi, które następnie łączy się w celu wykonania pracy. „Zwięzłość skryptu bash” nie była określonym pytaniem.
Kyle Jones,

7
PS: split+mvkombinacja jest ponad 6 razy szybsza niż awk(około 3s w porównaniu do 18s ) dla pliku wejściowego o wielkości 10 milionów linii (75 MB) ... tekst w każdym wierszu miał swój własny numer linii ... Dziękujemy za ponowne stwierdzenie „oczywiste” :)
Peter.O

3
PPS: Właśnie sprawdziłem to trochę dalej. Różnica prędkości jest związana z liczbą utworzonych plików w porównaniu z liczbą formatowań i obliczeń arytmetycznych, które awk wykonuje dla każdej linii bez względu na liczbę plików wyjściowych ... Przy użyciu tego samego pliku wejściowego jak w powyższym przykładzie: Gdy są 100 razy mniej plików, split + mvjest 75 razy szybszy niż awk: Gdy jest 100 razy więcej plików, split + mvjest 1,5 razy szybszy niż awk. Tak więc dla mnie ta split + mvmetoda wygrywa bez użycia rąk. Jest tak samo sumieniem (prawdopodobnie więcej) i jest szybszy niż awk.
Peter.O

1
jeśli martwisz się, że ma on 5 linii, spróbuj zamiast tego: for file in wrd.*; do mv "$file" "$file.txt"; done:)
Tony
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.