Разделение файлов с использованием tar, gz, zip или bzip2 [закрыто]

144

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

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

Ака
источник
3
Я чувствую вашу боль, но это не похоже на программирование.
Джейсон С
1
Многие программы сжатия (например, 7-Zip) могут разбивать сжатый файл на тома определенного размера для более легкого распространения.
Мартин Ливерсэйдж
Мне сказали, что это относится к superuser.com, но приватная бета-версия не начинается до завтра.
JesperE
Могу я спросить, зачем вам этот файл сжат?
Ян Jungnickel
Если одно из двух опубликованных здесь жизнеспособных решений не удастся, ему понадобится программное решение.
Джошуа

Ответы:

253

Вы можете использовать splitкоманду с -bопцией:

split -b 1024m file.tar.gz

Его можно собрать на компьютере с Windows, используя ответ @ Joshua .

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, чтобы использовать другой каталог для результирующих файлов. Кстати, если архив состоит только из одного файла, можно избежать 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.

matpie
источник
7
если вы не добавите префикс в качестве последнего аргумента после имени файла для разделения, вы получите выходные данные в файлах с именами xaa, xab, xac, xad ....
Чарли
@ Чарли, спасибо, я обновил свой ответ.
Matpie
2
На самом деле использование -b 1024MiBдало ошибку, что это было неправильное число байтов. Использование --bytes=1024mработ.
Брайан
И вам не нужно использовать, catчтобы собрать файл. Вы можете использовать copy /b file1 + file2 + etc..в Windows, затем скопировать обратно в Linux, и tar сможет прочитать заново собранный tarball. Я только что попробовал это.
Брайан
1
У Split есть опция --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 = boom.
Джошуа
+1 убедитесь, что файлы в правильном порядке!
Брайан
@ Джошуа Если честно, если нет, ты плохо назвал.
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
Эй, я копаю пост, ищущий только для этого. У меня нет ни команд, ни двоичных файлов split / zip на определенном устройстве, и это сработало отлично. Я подготовлю этот код для работы в качестве команды split :). Большое спасибо @ Адриан Панасюк. Это прекрасно для меня.
m3nda
@ erm3nda Добро пожаловать, рад, что это помогает!
Адриан Панасюк
Но я проверил, и в результате получился полный файл, а не разделенный. Как это может быть? Был большой файл на маленьком устройстве, поэтому был долгий процесс. Пожалуйста, проверьте свои решения при публикации :(
m3nda
@ erm3nda Вы никогда не говорили нам, что вам нужно избегать создания временного файла! Пожалуйста, смотрите второй вариант!
Адриан Панасюк