Файлы 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'
- исправить новые строки окон
- найти все строки, в которых нет -->
- найти все строки, которые не пусты (я думаю, что это быстрее, а может и нет)
- найти все строки, которые не являются просто числом
- удалить заголовок WEBVTT
- удалить переводы строк
- сжать несколько пробелов до 1
- удалить вкладки
- экранировать любые обратные косые черты (для json)
- экранировать любые двойные кавычки (для json)
Спасибо @steeldriver за исправление новых строк в Windows.
Я бы не стал использовать это в продакшене, так как это немного слабовато, например, оно будет пропускать строки текста типа «ты --> мой друг» и, возможно, несколько других случаев, но для моих целей этого должно быть достаточно (отправка в solr для поиска)
Я понимаю, что это довольно неэффективно. Я был бы признателен за советы по этому поводу.