Может файл, который был первоначально редок и затем расширенный быть сделанным редким снова?

'perl' решение:

Сценарий:

use warnings;                                                                                                                                                                       
use strict;                                                                                                                                                                         

die "Usage: perl $0 file\n" unless @ARGV == 1;                                                                                                                                      

my (%hash, $region);                                                                                                                                                                

open my $fh, "<", $ARGV[0] or die "Cannot open file $ARGV[0]: $!\n";                                                                                                                

while ( my $line = <$fh> ) {                                                                                                                                                        

        ## Get region, characters until first ':' without spaces at the beginning.                                                                                                  
        $region = $1 if $line =~ /^([^:\s]+)/;                                                                                                                                      

        ## Get names with a regex and save them as keys of a hash, values will be                                                                                                   
        ## regions.                                                                                                                                                                 
        if ( $line =~ /^\s*(?i:groups):\s*\[([^\]]*)\]\s*$/ ) {                                                                                                                     
                my @names = split /,\s*/, $1;                                                                                                                                       
                for my $name ( @names ) {                                                                                                                                           
                        push @{ $hash{ $name } }, $region;                                                                                                                          
                }                                                                                                                                                                   
        }                                                                                                                                                                           
}                                                                                                                                                                                   

## Read names (keys of the hash), open a file for each one and write regions on it.                                                                                                 
for my $name ( sort keys %hash ) {                                                                                                                                                  
        my $outfile = $name . ".txt";                                                                                                                                               
        open my $ofh, ">", $outfile or do { warn "Cannot open $outfile: $!\n"; next };                                                                                              
        print $ofh join( ", ", @{ $hash{ $name } } ), "\n";                                                                                                                         
        close $ofh or warn "Cannot close $outfile\n";                                                                                                                               
}                                                                                                                                                                                   

close $fh or warn "Cannot close $ARGV[0]\n";

Выполнение:

$ perl script.pl infile
29
04.04.2018, 15:41
4 ответа

Если Вы хотите сделать файл редким, можно сделать это непосредственно с dd.

dd if=./zeropadded.iso of=./isnowsparse.iso conv=sparse

От dd(1) руководство:

          sparse   If one or more output blocks would consist solely of
                   NUL bytes, try to seek the output file by the required
                   space instead of filling them with NULs, resulting in a
                   sparse file.

Так, обратите внимание, что это будет искать вперед, только если весь блок пуст. Для максимального использования разреженности bs=1.

8
27.01.2020, 19:38
  • 1
    Любой размер блока меньше, чем bs=512 действительно не имеет смысла, поскольку диски являются блочными устройствами. (bs=4096 в более новых дисках) –  lapo 22.01.2014, 13:06
  • 2
    похож, это эквивалентно cp --sparse=always zeropadded.iso isnowsparse.iso –  maxschlepzig 27.11.2016, 00:18

За исключением tar- луг это с a -S флаг (принимающий tar GNU) и повторно выполняющийся scp... нет. Никакая утилита, о которой я знаю, не имела бы способ знать, где "дыры" были.

2
27.01.2020, 19:38
  • 1
    GNU cp будет resparse файл: Из страницы справочника: Укажите - sparse=always для создания редкого файла DEST каждый раз, когда ИСХОДНЫЙ ФАЙЛ содержит достаточно длинную последовательность нулевых байтов. –  user25849 16.10.2012, 22:45
  • 2
    . Изучайте что-то каждый день - когда тот флаг был представлен? Платежи для чтения страниц справочника "известных" программ время от времени; D –  tink 16.10.2012, 23:09

Редактирование 2015

с util-linux 2.25, fallocate утилита на Linux имеет a -d/--dig-hole опция для этого.

fallocate -d the-file

Вырыл бы яму для каждого блока, полного нулей в файле


В более старых системах можно сделать это вручную:

Linux имеет a FALLOC_FL_PUNCH_HOLE опция к fallocate это может сделать это. Я нашел сценарий на GitHub с примером:

Использование FALLOC_FL_PUNCH_HOLE из Python

Я изменил его немного, чтобы сделать то, что Вы спросили - дыры перфорации в регионах файлов, которые заполнены нулями.Вот:

Используя FALLOC_FL_PUNCH_HOLE от Python до дыр перфорации в файлах

usage: punch.py [-h] [-v VERBOSE] FILE [FILE ...]

Punch out the empty areas in a file, making it sparse

positional arguments:
  FILE                  file(s) to modify in-place

optional arguments:
  -h, --help            show this help message and exit
  -v VERBOSE, --verbose VERBOSE
                        be verbose

Пример:

# create a file with some data, a hole, and some more data
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=0
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=2

# see that it has holes
$ du --block-size=1 --apparent-size test1
12288   test1
$ du --block-size=1 test1
8192    test1

# copy it, ignoring the hole
$ cat test1 > test2
$ du --block-size=1 --apparent-size test2
12288   test2
$ du --block-size=1 test2
12288    test2

# punch holes again
$ ./punch.py test2
$ du --block-size=1 --apparent-size test2
12288   test2
$ du --block-size=1 test2
8192    test2

# verify
$ cmp test1 test2 && echo "files are the same"
files are the same

Отметьте это punch.py только находит, что блоки 4 096 байтов выбивают, таким образом, это не могло бы сделать файл точно столь же редким, как это было, когда Вы запустили. Это могло быть сделано более умным, конечно. Кроме того, это только слегка тестируется, так быть осторожным и сделать резервные копии прежде, чем доверять ему!

30
27.01.2020, 19:38
  • 1
    мне нравится это лучшее, потому что он не требует перезаписи целого файла снова. –  Peter 24.07.2014, 12:13

Мне везло с этим:

cd whatever
rsync -avxWSHAXI . .

-Iсилы rsync для обновления всех файлов, независимо от того, думает ли это, что они изменились или нет; -S заставляет новые файлы быть sparsified. -a заставляет его произойти рекурсивно, таким образом, Вы можете sparsify целые деревья каталогов в одной команде.

Это не столь хорошо как сделанный на заказ инструмент, который находит дыры и уничтожает их с FALLOC_FL_PUNCH_HOLE, но это лучше, чем необходимость копировать все деревья каталогов.

2
27.01.2020, 19:38

Теги

Похожие вопросы