Podziel pliki za pomocą tar, gz, zip lub bzip2 [zamknięte]


144

Muszę skompresować duży plik o wielkości około 17-20 GB. Muszę podzielić go na kilka plików po około 1 GB na plik.

Szukałem rozwiązania w Google i znalazłem sposoby używania poleceń spliti cat. Ale w ogóle nie działały dla dużych plików. Ponadto nie będą działać w systemie Windows; Muszę go rozpakować na komputerze z systemem Windows.


3
Czuję twój ból, ale to nie wydaje się być związane z programowaniem.
— Jason S,

1
Wiele programów do kompresji (np. 7-Zip) jest w stanie podzielić skompresowany plik na woluminy o określonym rozmiarze, aby ułatwić dystrybucję.
— Martin Liversage,

To należy do superuser.com, ale prywatna beta zaczyna się dopiero jutro, jak mi powiedziano.
— JesperE

Czy mogę zapytać, dlaczego potrzebujesz skompresować ten plik?
— Jan Jungnickel

Jeśli jedno z dwóch opłacalnych rozwiązań zamieszczonych tutaj nie zadziała, będzie potrzebował rozwiązania programistycznego.
— Joshua

Odpowiedzi:


253

Możesz użyć splitpolecenia z -bopcją:

split -b 1024m file.tar.gz

Można go ponownie złożyć na komputerze z systemem Windows, używając odpowiedzi @ Joshua .

copy /b file1 + file2 + file3 + file4 filetogether

Edycja : Jak stwierdził @Charlie w poniższym komentarzu, możesz chcieć jawnie ustawić przedrostek, ponieważ użyje on xinaczej, co może być mylące.

split -b 1024m "file.tar.gz" "file.tar.gz.part-"

// Creates files: file.tar.gz.part-aa, file.tar.gz.part-ab, file.tar.gz.part-ac, ...

Edycja : edycja posta, ponieważ pytanie jest zamknięte, a najbardziej efektywne rozwiązanie jest bardzo zbliżone do treści tej odpowiedzi:

# create archives
$ tar cz my_large_file_1 my_large_file_2 | split -b 1024MiB - myfiles_split.tgz_
# uncompress
$ cat myfiles_split.tgz_* | tar xz

To rozwiązanie pozwala uniknąć używania dużego pliku pośredniego podczas (de) kompresji. Użyj opcji tar -C, aby użyć innego katalogu dla plików wynikowych. btw jeśli archiwum składa się tylko z jednego pliku, można uniknąć tar i używać tylko gzip:

# create archives
$ gzip -c my_large_file | split -b 1024MiB - myfile_split.gz_
# uncompress
$ cat myfile_split.gz_* | gunzip -c > my_large_file

W przypadku systemu Windows możesz pobrać przeniesione wersje tych samych poleceń lub użyć cygwin.


7
jeśli nie dodasz przedrostka jako ostatniego argumentu po nazwie pliku do podziału, otrzymasz dane wyjściowe w plikach o nazwach xaa, xab, xac, xad ....
— Charlie

@Charlie, dzięki, zaktualizowałem moją odpowiedź.
— matpie

2
W rzeczywistości użycie -b 1024MiBspowodowało błąd, że była to nieprawidłowa liczba bajtów. Korzystanie z --bytes=1024mutworów.
— Brian

I nie musisz używać go catdo ponownego złożenia pliku. Możesz użyć copy /b file1 + file2 + etc..w systemie Windows, a następnie skopiować z powrotem do Linuksa i tar może odczytać ponownie zmontowane archiwum. Właśnie tego spróbowałem.
— Brian

1
Split ma opcję --numeric-suffixes: użyj numerycznych sufiksów zamiast alfabetycznych.
— Dr Jan-Philip Gehrcke

27

Jeśli dzielisz się z Linuksem, nadal możesz ponownie złożyć w systemie Windows.

copy /b file1 + file2 + file3 + file4 filetogether

Możesz również użyć copy /b file* filetogether- support.microsoft.com/kb/71161
— eug

5
Działa to poprawnie tylko na NTFS i jeśli pliki są już w porządku sortowania NTFS. Wypróbuj na FAT lub FAT32 = boom.
— Joshua,

+1 upewnij się, że pliki są w odpowiedniej kolejności!
— Brian

@Joshua Aby być uczciwym, jeśli nie, wykonałeś kiepską robotę.
— jpmc26

@ jpmc26: Wiesz o złych nawykach zmiany kolejności katalogów w FAT32, prawda?
— Joshua,


8

Testowany kod, początkowo tworzy pojedynczy plik archiwum, a następnie dzieli go:

 gzip -c file.orig > file.gz
 CHUNKSIZE=1073741824
 PARTCNT=$[$(stat -c%s file.gz) / $CHUNKSIZE]

 # the remainder is taken care of, for example for
 # 1 GiB + 1 bytes PARTCNT is 1 and seq 0 $PARTCNT covers
 # all of file
 for n in `seq 0 $PARTCNT`
 do
       dd if=file.gz of=part.$n bs=$CHUNKSIZE skip=$n count=1
 done

Ten wariant pomija tworzenie pojedynczego pliku archiwum i przechodzi bezpośrednio do tworzenia części:

gzip -c file.orig |
    ( CHUNKSIZE=1073741824;
        i=0;
        while true; do
            i=$[i+1];
            head -c "$CHUNKSIZE" > "part.$i";
            [ "$CHUNKSIZE" -eq $(stat -c%s "part.$i") ] || break;
        done; )

W tym wariancie, jeśli rozmiar pliku archiwum jest podzielny przez $CHUNKSIZE, to ostatni plik częściowy będzie miał rozmiar 0 bajtów.


1
To splitjuż się dzieje.
— ephemient

1
ephemient Hej, mam wpis szukający właśnie tego. Nie mam poleceń / plików binarnych dzielenia ani zip na pewnym urządzeniu, a ten działał idealnie. Przygotuję ten kod do pracy jako polecenie split :). Dziękuję bardzo @Adrian Panasiuk. To dla mnie idealne.
— m3nda

@ erm3nda Nie ma za co, cieszę się, że to pomaga!
— Adrian Panasiuk

Ale przetestowałem i wynikiem był pełny plik, a nie podzielony. Jak to możliwe? Był to duży plik na małym urządzeniu, więc był to długi proces. Przetestuj swoje rozwiązania, wysyłając :(
— m3nda

@ erm3nda Nigdy nam nie powiedziałeś, że musisz unikać tworzenia pliku tymczasowego! Zobacz drugi wariant!
— Adrian Panasiuk
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.