16

У меня есть файл 500G, который я хотел бы разделить в linux, но у меня нет другого 500G бесплатно для запуска split(1) .

Существует ли инструмент или сценарий, который разбивает файл на месте на куски 1G, используя при этом минимальное дополнительное пространство?

3 ответа3

13
#!/bin/bash
# (c) whitequark 2010

set -e

if [ $# != 2 ]; then
  echo "Usage: $0 <filename> <part size>"
  echo "  This script will split file to multiple parts, starting from"
  echo "  the end, and truncating the original file in process."
  echo "  Part size is specified in bytes."
  echo "  Use at your own risk."
  exit 0
fi

filename=$1
partsize=$2

size=$(stat -c '%s' "${filename}")
parts=$(($size / $partsize))

do_split() {
  _part=$1
  _size=$2

  echo "Splitting part $_part"
  echo $(($partsize * ($_part - 1)))
  dd if="${filename}" of="${filename}.$(printf '%04d' $_part)" \
      count=1 bs=$partsize skip=$(($_part - 1))
  echo "Truncating source file"
  truncate "${filename}" --size="-$_size"
}

lastsize=$(($size % $partsize))
if [ $lastsize != 0 ]; then
  do_split $(($parts + 1)) $lastsize
fi

for i in $(seq $parts -1 1); do
  do_split $i $partsize
done

rm "${filename}"

gedit успешно запустился после разборки и сборки.

2

Я нашел скрипт @whitequark действительно полезным. Но я хотел разделить образ диска объемом 500 ГБ на несколько больших кусков по 50 ГБ каждый. Таким образом, скрипт потерпел неудачу, так как dd не может обработать такой большой параметр bs .

Поэтому я настроил скрипт для создания bs=1M и запроса мегабайт вместо байтов. Теперь я могу разделить на места и на действительно большие куски, используя, например, 50000 для 50 ГБ.

#!/bin/bash
# (c) whitequark 2010
# (c) dertalai 2015 (minimal modifications)

set -e

if [ $# != 2 ]; then
  echo "Usage: $0  "
  echo "  This script will split file to multiple parts, starting from"
  echo "  the end, and truncating the original file in process."
  echo "  Part size is specified in megabytes (1 MB = 1048576 bytes)."
  echo "  Use at your own risk."
  exit 0
fi

filename=$1
#partsize=$2
partsizeMB=$2
partsize=$(($2 * 1048576))

size=$(stat -c '%s' "${filename}")
parts=$(($size / $partsize))

do_split() {
  _part=$1
  _size=$2

  echo "Splitting part $_part"
  echo $(($partsize * ($_part - 1)))
  dd if="${filename}" of="${filename}.$(printf '%04d' $_part)" \
      count=$partsizeMB bs=1M skip=$((($_part - 1) * $partsizeMB))
  echo "Truncating source file"
  truncate "${filename}" --size="-$_size"
}

lastsize=$(($size % $partsize))
if [ $lastsize != 0 ]; then
  do_split $(($parts + 1)) $lastsize
fi

for i in $(seq $parts -1 1); do
  do_split $i $partsize
done

rm "${filename}"
1

У вас действительно есть файл на 500 ГБ? Если вы генерируете файл объемом 500 ГБ, архивируя папку или диск, а затем пытаясь разделить его, вы можете разделить его на лету, передавая вывод команды tar (или того, что вы используете) в split:

sudo tar cvjsp /Volumes/BackupDisk/Backups.backupdb/ | \
     split -d -b 4480m - Backups.backupdb.tar.bz2.

Это сделает раскол размером в DVD из архива моей базы данных Time Machine. Тем не менее, он делает их все сразу, а это значит, что он действительно не делает то, что вы ищете.

Смотрите мой вопрос здесь для получения дополнительной информации. Сценарий Уайткварка может быть полезен с небольшой поправкой! Я должен попробовать это.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .