Как я могу разделить текстовый файл на несколько текстовых файлов с помощью Perl?

Во время установки можно настроить корневой каталог, как Вам нравится. После установки можно отредактировать /etc/fstab включать точку монтирования для корневого каталога.

Так как FAT не поддерживает полномочия, это не желательно как раздел для /home точка монтирования; Вы не сможете ограничить доступ к своим файлам, и некоторые программы не будут работать. Вместо этого используйте ext2 раздел и установите драйвер ext2 Windows.

4
13.02.2013, 18:07
5 ответов

Это будет работать на данный формат. Это предполагает, что файл будет всегда запускаться с 00:00:00:00.

#!/usr/bin/env perl

use strict;
use warnings;

open(my $infh, '<', 'ABC_TabDelim.txt') or die $!;

my $outfh;
my $filecount = 0;
while ( my $line = <$infh> ) {
    if ( $line =~ /^00:00:00:00/ ) {
        close($outfh) if $outfh;
        open($outfh, '>', sprintf('ABC%02d_TabDelim.txt', ++$filecount)) or die $!;        
    }
    print {$outfh} $line or die "Failed to write to file: $!";
}

close($outfh);
close($infh);
3
27.01.2020, 20:47
  • 1
    Не используйте regexp, если Вы не имеете к, использовать if (substr($line, 0, 11) eq "00:00:00:00"). –  goldilocks 13.02.2013, 18:20
  • 2
    @goldilocks: что? regex выражает намерение очень хорошо и избегает необходимости считать символы (и упущение обновить что-то, если шаблон когда-нибудь изменяется). –  Mat 13.02.2013, 18:43
  • 3
    @Mat Слишком плохо мы испытываем недостаток в a string.startswith() метод, который решает ту проблему :). –  jordanm 13.02.2013, 18:46
  • 4
    @Mat: метод здесь является очень незначительными различиями WRT к обслуживанию ("упущение обновить... ") значений hardcoded (но укажите взятый). Это не имеет большого значения просто я считал бы это плохим программированием, потому что regexp менее эффективен, мудрый ресурс, и использование их для всего довольно чрезмерно ленив. Никакое преступление ;) Кроме того, использование substr () является более определенным оператором о том, что Вы делаете (точное совпадение). –  goldilocks 13.02.2013, 18:58

Вот. Никакая проверка ошибок, выполненная как, например, perl split file-to-munge

Обновление: очистка Сценария, как предложено лютиком золотистым

#!/usr/bin/perl

$n = 1;
while(<>) {
    if(/^00:00:00:00/) {
        close($out) if(n != 1);
        $fn = sprintf("ABC%02d_TabDelim.txt", $n++);
        open($out, ">", "$fn");
    }
    print OUT;
}
3
27.01.2020, 20:47
  • 1
    1 для использования шарика ФАЙЛА и 2 открытых аргументов!Прошу прощения. –  goldilocks 13.02.2013, 18:24
  • 2
    @goldilocks, который является довольно идиоматическим Perl 5... –  vonbrand 13.02.2013, 18:25
  • 3
    Это на самом деле идиоматично из Perl <5.6 (c.2000), когда это был единственный выбор (см. здесь: perldoc.perl.org / …) существует много объяснений вокруг того, почему это - дурная привычка, (например: securecoding.cert.org/confluence/pages / …), не, наименьшее количество которого является теми bareword typeglob дескрипторы, находятся по умолчанию в глобальном пространстве имен независимо от того, где Вы объявляете их. socialtext.net/perl5/bareword_uppercase_filehandles –  goldilocks 13.02.2013, 18:37
  • 4
    @goldilocks, и это важно для одноразового сценария потому что...? –  vonbrand 13.02.2013, 18:42
  • 5
    я не downvoting, но демонстрация плохих методов новому пользователю, не является хорошей вещью. Для Вашего собственного предмета одноразового использования это прекрасно. –  jordanm 13.02.2013, 18:48

Если вывод для того демонстрационного входа, как будут ожидать, будет 4 файлами, каждым с 3 строками, при этом каждая 1-я строка является одним запуском с “00:00:00:00” и другими 2 строками следующие, это сделает это:

perl -ne 'if(/^[0:]{11}/){close F if$f;open F,sprintf(">ABC%02d_TabDelim.txt",++$f)}print F' ABC_TabDelim.txt
2
27.01.2020, 20:47

Вам не нужен Perl для который: можно использовать стандартную утилиту оболочки csplit. Существует одно ограничение: название выходных файлов должно быть xxx00, xxx01, и т.д., таким образом, необходимо будет добавить желаемый суффикс впоследствии.

csplit -s -f ABC ABC_TabDelim.txt '/^00:00:00:00/' '{999999999}'
rm ABC00  # empty file (containing everything up to the first 00:00:00:00)
for x in ABC[0-9][0-9]; do mv "$x" "${x}_TabDelim.txt"; done

{*} аргументом для повторения предыдущего разделителя максимально много раз является расширение GNU. POSIX csplit требует первичной обработки с grep.

2
27.01.2020, 20:47

У Вас есть решение для жемчуга, вот один способ, которым Вы могли сделать это с awk:

awk '/00:00:00:00/ { out = sprintf("ABC%02d_TabDelimit.txt", ++i) } { print > out }' ABC_TabDelim.txt

Если бы необходимо разделить на многие файлы, Вы хотели бы закрыть каждый файл, как Вы продвигаетесь, предварительно ожидаете функцию sprintf с if(out) close(out):

awk '/00:00:00:00/ { if(out) close(out); out = sprintf("ABC%02d_TabDelimit.txt", ++i) } { print > out }' ABC_TabDelim.txt
1
27.01.2020, 20:47

Теги

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