Как преобразовать .txt файл подзаголовка в .srt формат?

Можно сделать grep произведите имя файла с -H, и затем используйте awk записать в него.

$ grep -H regexp files*  | awk -F : '{ file="matches-" $1; sub("^[^:]+:","",$0); print $0 > file; }'
3
26.01.2014, 21:45
2 ответа

Это очень похоже на подход @goldilock, но, IMO, более просто и может иметь дело с пустыми строками в файле и заменах | с разрывом строки:

#!/usr/bin/env perl
my ($time, $text, $next_time, $next_text);
my ($c,$i)=0;
while (<>) {
    ## skip bad lines
    next unless /^\s*([:\d]+)\s*:(.+)/;
    ## If this is the first line. I could have used $. but this is
    ## safer in case the file contains an empty line at the beginning.
    if ($c == 0) {
      $time=$1; 
      $text=$2;
      $c++;
    }
    else {
      ## This is the counter for the subtitle index
      $i++;
      ## Save the current values
      $next_time=$1; 
      $next_text=$2;     
      ## I am assuming that the | should be interpreted
      ## as a newline, remove this if I'm wrong.
      $text=~s/\|/\n/g;     
      ## Print the previous subttitle
      print "$i\n$time,100 --> $next_time,000\n$text\n\n";        
      ## Save the current one for the next line
      $time=$next_time; $text=$next_text;
    }
}     
## Print the last subtitle. It will be dislayed for a minute
## 'cause I'm lazy.
$i++;
$time=~/(\d+:)(\d+)(:\d+)/;
my $newtime=$1 . (sprintf "%02d", $2+1) . $3;
print "$i\n$time,100 --> $newtime,000\n$text\n\n";    

Сохраните сценарий как файл и сделайте его исполняемым файлом, затем работайте:

./script.pl subfile > good_subs.srt

Вывод я вхожу в Ваш образец, был:

1
00:00:44,100 --> 00:01:01,000
" Myślę, więc jestem".
Kartezjusz, 1596-1650

2
00:01:01,100 --> 00:01:06,000
Trzynaste Pietro

3
00:01:06,100 --> 00:01:10,000
Podobno niewiedza uszczęśliwia.

4
00:01:10,100 --> 00:01:13,000
Po raz pierwszy w życiu
zgadzam się z tym.

5
00:01:13,100 --> 00:01:15,000
Wolałbym...

6
00:01:15,100 --> 00:01:19,000
nigdy nie odkryć
tej straszliwej prawdy.

7
00:01:19,100 --> 00:02:19,000
Teraz już wiem...
4
27.01.2020, 21:14
  • 1
    Последний подзаголовок в Вашем выводе заканчивается за 0.1 секунды до того, как он запустится! –  goldilocks 26.01.2014, 22:03
  • 2
    Это работает вполне прилично. Я просто должен настроить некоторые записи, потому что они отображены для немного слишком долго. Возможно, существует способ поместить это в сценарий, скажем, 5-8secs максимум. Если Вы хотите экспериментировать больше с подзаголовками, я загрузил его на pasebin: pastebin.com/vZP419eG –  Mikhail Morfikov 26.01.2014, 22:08
  • 3
    @goldilocks чертовски, извините, забыл use Time::Machine :). Спасибо, зафиксированное. –  terdon♦ 26.01.2014, 22:36
  • 4
    @MikhailMorfikov это возможно, но увеличивает сложность, потому что это означает, что мы должны управлять временами, так, чтобы 1:59 + 20 = 2:19. Это означает или сложный код или использование внешних модулей и казалось вне объема вопроса. –  terdon♦ 26.01.2014, 22:38
  • 5
    +1 Хорошее задание. В течение времени Вы могли использовать алгоритм на основе длины текстовой строки, сказать 1/2 секунду на символ, но не превышение запуска следующего заголовка. –  goldilocks 27.01.2014, 11:55

Какой предназначенный Thorsten является чем-то вроде этого:

#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);

my $END = '!!ZZ_END';
my $LastTitleDuration = 5;

my $count = 1;
my $line = <STDIN>;
chomp $line;
my $next = <STDIN>;
while ($line) {
    $next = lastSubtitle($line) if !$next;
    last if !$next;
    chomp $next;
    if (!($next =~ m/^\d\d:\d\d:\d\d:.+/)) { 
        print STDERR 'Skipping bad data at line '.($count+1).":\n$line\n";
        $next = <STDIN>;
        next;
    }
    printf STDOUT
        "%d\r\n%s,100 --> %s,000\r\n%s\r\n\r\n",
        $count++,
        substr($line, 0, 8),
        substr($next, 0, 8),
        substr($line, 9)
    ;
} continue {
    $line = $next;
    $next = <STDIN>;
}

sub lastSubtitle {
    my $line = shift;
    $line =~ /^(\d\d:\d\d:)(\d\d):(.+)/;
    return 0 if $3 eq $END;
    return sprintf("$1%2d:$END", $2 + $LastTitleDuration);
} 

Когда я подаю Ваши демонстрационные данные в это, я добираюсь:

1
00:00:44,100 --> 00:01:01,000
" Myślę, więc jestem".|Kartezjusz, 1596-1650

2
00:01:01,100 --> 00:01:06,000
Trzynaste Pietro

3
00:01:06,100 --> 00:01:10,000
Podobno niewiedza uszczęśliwia.

4
00:01:10,100 --> 00:01:13,000
Po raz pierwszy w życiu|zgadzam się z tym.

5
00:01:13,100 --> 00:01:15,000
Wolałbym...

6
00:01:15,100 --> 00:01:19,000
nigdy nie odkryć|tej straszliwej prawdy.

7
00:01:19,100 --> 00:01:24,000
Teraz już wiem...

Несколько точек:

  • Подзаголовки на самом деле запускают 1/10-ю секунду, позднюю, таким образом, они не накладываются, и потому что я был слишком ленив для добавления в некоторой математике, включающей вторую метку времени. Они затем остаются до 1/10-й секунды перед следующим заголовком.

  • Последний заголовок не ложится спать для $LastTitleDuration (5 секунд).

  • Я использовал окончания строки CRLF согласно статье Википедии SupRip, хотя это не может быть необходимо.

  • Это предполагает, что первая строка входа не уродлива. Кроме того, они проверяются, и об ошибках сообщают stdout, таким образом:

    readAlongToSRT.pl < readAlong.txt > whatever.srt
    

    Должен создать файл, но все еще распечатать ошибки на экран.

  • Обработка остановится в пустой строке.

  • См. комментарий terdon ниже ре: возможное значение | в содержании подзаголовка. Можно хотеть вставить $line =~ s/|/\r\n/g; перед printf STDOUT строка.

Это взяло меня 20 минут и единственные данные тестирования, которые я имел, были те 7 строк, не рассчитывайте на них являющийся прекрасным. Если существуют когда-нибудь разрывы строки в подзаголовках, которые вызовут проблему. Я предположил, что нет; если это так, я предлагаю, чтобы Вы удалили их из входа сначала вместо того, чтобы пытаться иметь дело с ними здесь.

2
27.01.2020, 21:14
  • 1
    Чертовски, победите меня к нему и использование того же подхода! Хороший один, +1. Я думаю что | в исходном формате должен быть изменен на \n но это - просто предположение. –  terdon♦ 26.01.2014, 21:08
  • 2
    @terdon Хм, да который мог бы иметь смысл. –  goldilocks 26.01.2014, 21:10

Теги

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