Слияние разделяет на блоки из нескольких файлов

Вы, вероятно, нашли бы более продуктивным или предварительно загрузить или статическая ссылка libstdc ++ вместо этого.

1
31.03.2013, 23:35
2 ответа

Что-то вроде этого жемчуг должно работать. Замените имена файлов в соответствующих случаях.

#!/usr/bin/env perl

use strict;
use warnings;
use IO::Handle;

open(my $list_fh, '<', 'somefile') or die "Failed to open list file: $!";
open(my $out_fh, '>', 'outfile') or die "Failed to open out file: $!";
my $merge_fh = IO::Handle->new();
my $cur_fname = q{};
my $buff;

while ( my $line = <$list_fh> ) {
    next if $line =~ /^\s?#/;
    chomp($line);
    my ($fname, $begin, $end) = split(/\s+/, $line);
    if ( $cur_fname ne $fname ) {
        $merge_fh->close() if $merge_fh->opened();
        open($merge_fh, '<', $fname) or die "Failed to open file: $!";
        $cur_fname = $fname;
    }

    seek($merge_fh, $begin, 0);
    read($merge_fh, $buff, $end - $begin);
    print {$out_fh} $buff or die "Failed to write to $cur_fname: $!";
}

$merge_fh->close();
$out_fh->close();
$list_fh->close();
2
27.01.2020, 23:21
  • 1
    Здорово! Просто мог перестать работать, если блоки становятся слишком большими, возможно, нарубили read/print в цикл. –  vonbrand 01.04.2013, 01:25
  • 2
    @vonbrand я не делаю замеченный ничто документация perl read() или страница справочника моей ОС для fread() это указывает, что существует некоторое ограничение к этому. Вы означаете от отсутствия RAM держать данные? –  jordanm 01.04.2013, 01:34
  • 3
    Точно. Мог бы продвинуть его в свопинг. –  vonbrand 01.04.2013, 01:36
  • 4
    я ищу небольшое и изящное решение вместо того, чтобы писать новую программу. Так или иначе это - хороший ответ! –  Pedro Lacerda 01.04.2013, 02:37
  • 5
    @Kanvuanza Это не острота, но я считал бы это "маленьким" сценарием. –  jordanm 01.04.2013, 02:38

С zsh:

zmodload zsh/mapfile
while read -r f b e; do
  [ -f $f ] && printf %s ${${mapfile[$f]}[b+1,e+1]}
done < list.txt > merged

Не становитесь слишком восторженными все же. $mapfile действительно использует mmap но читает целый файл в памяти. (см. info zsh 'The zsh/mapfile Module' для деталей).

С ksh93:

PATH=/opt/ast/bin:$PATH export PATH
while read -r f b e; do
  [[ -f $f ]] && head -c "$((e-b+1))" < "$f" <#(($b))
done < list.txt > merged

При устанавливании ПУТИ тот путь состоит в том так, чтобы head будьте ksh93 встроенным (даже если существует нет /opt/ast/bin каталог). <#((n)) frontend ksh93 к lseek.

PATH=/opt/ast/bin:$PATH export PATH
while read -r f b e; do
  [[ -f $f ]] && head -c "$((e-b+1))" -s "$b" < "$f"
done < list.txt > merged

ksh93 head имеет -s опция пропустить данные (использование lseek внутренне для регулярных файлов). Это работало бы пока ksh93 был создан с head встроенный включенный.

2
27.01.2020, 23:21
  • 1
    Соответствующие информационные переговоры по странице об отображении имен файлов для регистрации содержания через ассоциативный массив, не там более прямой способ вытащить диапазон из файла? Я не могу найти, что синтаксис Perly на файле располагается любой (не, никакой zsh пользователь). –  vonbrand 01.04.2013, 01:50
  • 2
    Очень полезный модуль, я протестирую с реальными данными завтра, но кажусь довольно быстрым. Когда отображаемый файл освобожден из памяти? Я волнуюсь по поводу заполнения RAM, потому что 4 или 6 файлов могут легко достигнуть 100 МБ. –  Pedro Lacerda 01.04.2013, 02:49

Теги

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