Розділити файли за допомогою tar, gz, zip або bzip2 [закрито]


144

Мені потрібно стиснути великий файл розміром близько 17-20 ГБ. Мені потрібно розділити його на кілька файлів розміром близько 1 Гб на файл.

Я шукав рішення через Google і знаходив способи використання splitта catкоманд. Але вони не працювали для великих файлів взагалі. Крім того, вони не працюватимуть у Windows; Мені потрібно витягнути його на машині Windows.


3
Я відчуваю ваш біль, але це, здається, не пов'язане з програмуванням.
Jason S

1
Багато програм стиснення (наприклад, 7-Zip) здатні розділити стислий файл на томи заданого розміру для легшого розповсюдження.
Мартін Ліверсайз

Це належить на superuser.com, але приватна бета-версія починається до завтра, як мені кажуть.
JesperE

Чи можу я запитати, для чого вам потрібен цей файл стислий?
Jan Jungnickel

Якщо одне з двох життєздатних рішень, розміщених тут, не зникає, йому буде потрібно програмне рішення.
Джошуа

Відповіді:


253

Ви можете використовувати splitкоманду з -bопцією:

split -b 1024m file.tar.gz

Його можна знову зібрати на машині Windows, використовуючи відповідь @ Джошуа .

copy /b file1 + file2 + file3 + file4 filetogether

Редагувати : Як зазначено в коментарі нижче @Charlie, ви можете встановити префікс прямо, оскільки він буде використовуватись xінакше, що може заплутати.

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, ...

Редагувати : Редагування публікації, оскільки питання закрите, а найефективніше рішення дуже близьке до змісту цієї відповіді:

# 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

Це рішення дозволяє уникнути необхідності використовувати проміжний великий файл при (де) стисканні. Використовуйте опцію tar -C, щоб використовувати інший каталог для отриманих файлів. btw, якщо архів складається лише з одного файлу, можна уникати tar і використовувати лише gzip:

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

Для Windows ви можете завантажити перенесені версії тих же команд або використовувати cygwin.


7
якщо ви не додасте префікс як останній аргумент після імені файлу для розбиття, ви отримаєте вихід у файлах на ім'я xaa, xab, xac, xad ....
Charlie

@Charlie, дякую, я оновив свою відповідь.
матір

2
Насправді використання -b 1024MiBдало помилку, що це недійсна кількість байтів. Використання --bytes=1024mтворів.
Брайан

І вам не доведеться використовувати catдля збирання файлу. Ви можете використовувати copy /b file1 + file2 + etc..в Windows, потім копіювати назад в Linux, а tar може прочитати повторно зібраний тарбол. Я просто спробував це.
Брайан

1
Спліт має можливість --numeric-suffixes: використовувати числові суфікси замість алфавіту.
Д-р Ян-Філіп Геркк

27

Якщо ви відокремлюєтеся від Linux, ви все ще можете зібрати в Windows.

copy /b file1 + file2 + file3 + file4 filetogether

Ви також можете скористатися copy /b file* filetogether- support.microsoft.com/kb/71161
eug

5
Це працює правильно лише в NTFS, і якщо файли вже в порядку сортування NTFS. Спробуйте його на FAT або FAT32 = бум.
Джошуа

+1 переконайтесь, що файли у правильному порядку!
Брайан

@Joshua Щоб бути справедливим, якщо їх немає, ви зробили погану назву.
jpmc26

@ jpmc26: Ви знаєте про шкідливі звички в перепорядкуванні FAT32, чи не так?
Джошуа


8

Тестований код спочатку створює один архівний файл, а потім розбиває його:

 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

Цей варіант не дозволяє створити єдиний архівний файл і переходить безпосередньо до створення частин:

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; )

У цьому варіанті, якщо розмір файлу архіву ділиться на $CHUNKSIZE, то останній частковий файл матиме розмір файлу 0 байт.


1
Ось що splitвже робить.
ефемія

1
ephemient Ей, я копав якусь посаду, шукаючи саме ТОМУ. У мене на певному пристрої немає розділених команд / поштових команд / двійкових файлів, і цей відмінно працював. Я підготую цей код, щоб він працював як розділена команда :). Дуже дякую @Adrian Panasiuk Це для мене чудово.
м3нда

@ erm3nda Ласкаво просимо, радий, що це допомагає!
Адріан Панасюк

Але я перевірив, і результат отримав повний файл, а не спліт. Як це може бути? Був великий файл на невеликому пристрої, тому процес тривалий. Будь ласка, протестуйте свої рішення під час публікації :(
m3nda

@ erm3nda Ви ніколи не говорили нам, що вам потрібно уникати створення тимчасового файлу! Будь ласка, подивіться другий варіант!
Адріан Панасюк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.