извлечь текст из vtt-файла

извлечь текст из vtt-файла

Файлы vtt выглядят так:

WEBVTT

1
00:00:00.096 --> 00:00:05.047
you're the four functions if you would of 
management first of all you have the planning

2
00:00:06.002 --> 00:00:10.079
the planning stages basically you were choosing appropriate 
 organizational goals and courses

3
00:00:11.018 --> 00:00:13.003
action to best achieve those goals

Мне нужен только текст, например такой:

you're the four functions if you would of management first of all you have the planning the planning stages basically you were choosing appropriate organizational goals and courses action to best achieve those goals

на ubuntu я пробовал:

cat file.vtt | grep -v [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9][[:space:]][[:punct:]][[:punct:]][[:punct:]][[:space:]][0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]

что дает мне:

WEBVTT

1
you're the four functions if you would of 
management first of all you have the planning

2
the planning stages basically you were choosing appropriate 
 organizational goals and courses

3
action to best achieve those goals

но я не могу понять, как сделать остальное. Я хочу заменить

\n[0-9]+\n\nс пробелом, но я не могу понять, как заставить sed или grep сделать это.

как мне с помощью базового / портативного ПО (например, обычно предустановленного в Ubuntu, CentOS и т. д., например, команды grep, sed или tr) получить только необработанный текст без синхронизации субтитров, и все в одной строке (без переводов строк)?

ПРИМЕЧАНИЕ: это должно работать для других языковых символов, таких как китайский, хинди, арабский, поэтому желательно не использовать совпадения типа [az], а вместо этого удалить временные линии, которые очень последовательны по формату. Также не удаляйте слепо любые цифры, так как текст может содержать цифры

ПРИМЕЧАНИЕ 2: конечная цель — сделать текст безопасным для значения JSON, поэтому все специальные символы удалены, а двойные кавычки экранированы, но это выходит за рамки данного вопроса.

решение1

Поскольку ваш файл, по-видимому, состоит из последовательности записей, разделенных одной или несколькими пустыми строками, я бы предложил попробовать что-то на основережимы абзацалибо , awkлибо perl.

Например, если вам всегда нужно удалять первые две строки, например

1
00:00:00.096 --> 00:00:05.047

вы можете разбить текст на поля, разделенные пробелами, внутри абзацев, разделенных пробелами, и пропустить первые два поля, используя либо

awk -vRS= -vORS= -F'\n' '{for(j=3;j<=NF;j++) print $j; print " "}' file.vtt

или

perl -F'\n' -00ne 'print join("", @F[2..$#F]), " "' file.vtt

Если вы не можете рассчитывать на фиксированное количество полей (строк), которые нужно удалить, то довольно просто добавить проверку регулярного выражения — немного проще, perlпоскольку она позволяет нам работать grepнапрямую с массивами, а не писать явный цикл. Например, чтобы разбить записи на записи, разделенные пробелами, а затем вывести только те поля (строки), которые имеют хотя бы одну последовательность из как минимум 3 буквенных символов, вы можете использовать

perl -F'\n' -00ane '
  print join("", grep { /[[:alpha:]]{3}/ } @F), " "
' file.vtt

Если вы хотите исключить WEBVTTстроку, вы можете просто пропустить первую запись, т.е.

perl -F'\n' -00ane '
  print join("", grep { /[[:alpha:]]{3}/ } @F), " " if $. > 1
  ' file.vtt

Вам придется выбрать подходящее регулярное выражение, которое захватит нужные строки и исключит нежелательные. Вы можете добавить блок ENDв любой из них awkили perl, если хотите, добавить заключительную новую строку в объединенный вывод.


ПРИМЕЧАНИЕ: поскольку (судя по обсуждению в комментариях) ваши файлы, по-видимому, имеют CRLFокончания строк в стиле DOS, вам придется с этим разобраться — либо изменив соответствующим образом разделители полей и записей в приведенных выше командах, либо удалив CRпервую букву s, например

sed 's/\r$//' file.vtt | 
  perl -F'\n' -00ane '
    print join("", grep { /[[:alpha:]]{3}/ } @F), " " if $. > 1
  '
you're the four functions if you would of management first of all you have the planning the planning stages basically you were choosing appropriate  organizational goals and courses action to best achieve those goals steeldriver@xenial-vm:~/test/$

решение2

хорошо, вот что у меня получилось

#!/bin/bash
fname=$1
sed 's/\r$//' "$fname"    |\
grep -v -- "-->"          |\
grep -v "^$"              |\
grep -E -v "^[0-9]+$"     |\
sed 's/WEBVTT//'          |\
tr '\n' ' '               |\
tr -s ' '                 |\
tr -d '\t'                |\
sed 's/\\/\\\\/g'         |\
sed 's/"/\\"/g' 
  1. исправить новые строки окон
  2. найти все строки, в которых нет -->
  3. найти все строки, которые не пусты (я думаю, что это быстрее, а может и нет)
  4. найти все строки, которые не являются просто числом
  5. удалить заголовок WEBVTT
  6. удалить переводы строк
  7. сжать несколько пробелов до 1
  8. удалить вкладки
  9. экранировать любые обратные косые черты (для json)
  10. экранировать любые двойные кавычки (для json)

Спасибо @steeldriver за исправление новых строк в Windows.

Я бы не стал использовать это в продакшене, так как это немного слабовато, например, оно будет пропускать строки текста типа «ты --> мой друг» и, возможно, несколько других случаев, но для моих целей этого должно быть достаточно (отправка в solr для поиска)

Я понимаю, что это довольно неэффективно. Я был бы признателен за советы по этому поводу.

Связанный контент