Czy w Linuksie są jakieś narzędzia do dzielenia pliku na miejscu?

16

Mam plik 500G, który chciałbym podzielić na Linuksa, ale nie mam kolejnego 500G do uruchomienia split(1).

Czy istnieje narzędzie lub skrypt, który podzieli plik w miejscu na fragmenty 1G przy minimalnym dodatkowym miejscu?

ngoozeff
źródło

Odpowiedzi:

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 z powodzeniem uruchomił się po ponownym złożeniu i ponownym złożeniu.

Whitequark
źródło
2
Pamiętaj, że możesz użyć 'dd if = / dev / null of = "$ {nazwa pliku}" seek = 1 bs = $ (($ rozmiar - $ _size))', jeśli z jakiegoś powodu nie masz skróconego
ngoozeff
1
Dzięki, skrypt działa świetnie! Jeśli coś pójdzie nie tak, nie chcemy usuwać pliku, lepiej w ostatniej linii:if [ $(stat -c '%s' "${filename}") == 0 ]; then rm "${filename}" fi
Oleg Mikheev
Należy również wspomnieć, że ten skrypt wymaga dodatkowego miejsca, które jest równe rozmiarowi części (jeśli
rozbijesz
Dodam, że kiedy przekazałem wartość 10737418240, tj. 10 GB, błędnie utworzyłem pliki 2 GB. Dzieliłem 300 GB pliku i miałem 30 GB wolnego miejsca.
Xavier Leprêtre
3

Uważam, że skrypt @whitequark jest bardzo przydatny. Ale chciałem podzielić obraz dysku o pojemności 500 GB na kilka dużych fragmentów o wielkości około 50 GB każdy. W ten sposób skrypt nie powiódł się, ponieważ ddnie może obsłużyć tak dużego bsparametru.

Więc dostosowałem skrypt do tworzenia bs=1Mi proszenia o megabajty zamiast bajtów. Teraz mogę dzielić na miejsce i na naprawdę duże fragmenty, używając na przykład 5000050 GB.

#! / bin / bash
# (c) Whitequark 2010
# (c) dertalai 2015 (minimalne modyfikacje)

ustaw -e

jeśli [$ #! = 2]; następnie
  echo „Użycie: 0 $”
  echo „Ten skrypt podzieli plik na wiele części, zaczynając od„
  echo „koniec i obcinanie oryginalnego pliku w toku”.
  echo „Rozmiar części jest określony w megabajtach (1 MB = 1048576 bajtów).”
  echo „Używaj na własne ryzyko”.
  wyjście 0
fi

nazwa pliku = 1 $
# części = 2 USD
partsizeMB = 2 USD
rozmiar części = $ ((2 $ * 1048576))

size = $ (stat -c '% s' "$ {nazwa pliku}")
części = $ ((rozmiar $ / rozmiar części))

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

  echo „Część dzieląca $ _part”
  echo $ (($ partsize * ($ _part - 1)))
  dd if = "$ {nazwa pliku}" z = "$ {nazwa pliku}. $ (printf '% 04d' $ _part)" \
      count = $ partsizeMB bs = 1 mln pominąć = $ ((($ _ część - 1) * $ partsizeMB))
  echo „Obcinanie pliku źródłowego”
  obetnij „$ {nazwa pliku}” --size = "- $ _ rozmiar"
}

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

dla i w $ (kolejne części -1 -1); zrobić
  do_split $ i $ partsize
gotowy

rm „$ {nazwa pliku}”
Dertalai
źródło
1

Czy faktycznie masz już plik 500 GB? Jeśli generujesz plik o pojemności 500 GB, archiwizując folder lub dysk, a następnie próbując go podzielić, możesz podzielić go w locie, przesyłając dane wyjściowe tar (lub cokolwiek, czego używasz) do podziału:

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

Spowoduje to podział wielkości DVD archiwum mojej bazy danych Time Machine. Jednak sprawia, że ​​wszystkie są naraz, co oznacza, że ​​tak naprawdę nie robi tego, czego szukasz.

Zobacz moje pytanie tutaj, aby uzyskać więcej informacji. Skrypt Whitequarka może być tam przydatny z niewielkimi modyfikacjami! Będę musiał spróbować.

Kevin Vermeer
źródło