Как я могу удалить все английские строки из текстового файла?

11

У меня есть этот текстовый файл:

714
01:11:22,267 --> 01:11:27,731
Auch wenn noch viele Generationen auf einen Wechsel hoffen,
Even if it takes many generations hoping for a change,

715
01:11:27,732 --> 01:11:31,920
werde ich mein Bestes geben
und hoffe, dass andere das gleiche tun.
I'm giving mine, I'm doing my best
hoping the other will do the same

716
01:11:31,921 --> 01:11:36,278
Wir haben eine harte Arbeit vor uns, 
um den Lauf der Dinge zu ändern. 
it's going to be hard work
for things to turn around.

717
01:11:36,879 --> 01:11:42,881
Wenn man die Zentren künstlicher Besamung, 
die Zuchtlaboratorien und die modernen Kuhställe besichtigt, 
When visiting artificial insemination centers,
the selection center, modern stables,
...

и хотел бы разобрать, чтобы остались только неанглийские строки

Это возможно?

Дил Ма
источник
3
Можете ли вы смело предположить, что на каждом языке всегда будет одинаковое количество строк? Если есть две немецкие линии, всегда будут две английские линии и т. Д.?
Тердон

Ответы:

13

Есть трудный путь и намного более легкий путь. Сложный способ - использовать синтаксический анализ на естественном языке, чтобы получить вероятность того, что данная строка написана на английском языке, и отбросить такие строки.

Проще всего взять список английских стоп-слов и удалить строки, содержащие элементы из этого списка. Если вы хотите уменьшить вероятность неправильной категоризации строки, вы также можете найти наличие немецких стоп-слов в строках, которые вы не можете отклонить, чтобы убедиться, что они, вероятно, являются немецкими.

Вот очень быстрый и грязный скрипт для использования связанного списка стоп-слов для фильтрации:

#!/usr/bin/python
english_stop = set()
with open('english-stop-words.txt') as estop:
    for line in estop:
        bar = line.find('|')
        if bar > -1:
            line = line[0:bar]
        line = line.strip()
        if line:
            english_stop.add(line)

with open('mixed-german.txt') as mixg:
    for line in mixg:
        for word in line.lower().split():
            if word in english_stop:
                break
        else:
            print line[:-1]

и вывод:

714
01:11:22,267 --> 01:11:27,731
Auch wenn noch viele Generationen auf einen Wechsel hoffen,

715
01:11:27,732 --> 01:11:31,920
werde ich mein Bestes geben
und hoffe, dass andere das gleiche tun.

716
01:11:31,921 --> 01:11:36,278
Wir haben eine harte Arbeit vor uns, 
um den Lauf der Dinge zu ändern. 

717
01:11:36,879 --> 01:11:42,881
Wenn man die Zentren künstlicher Besamung, 
die Zuchtlaboratorien und die modernen Kuhställe besichtigt, 

Немного более полная версия должна игнорировать различные знаки препинания, такие как ,.апостроф в английском языке, но не 'внутри слова. Еще большую точность можно получить, если искать кодовые точки, которые никогда не встречаются на английском языке (например «ßü), но это оставлено в качестве упражнения для читателя.

MSW
источник
Очень хороший подход. Гораздо лучше, чем мой взлом и слэш 8-)
slm
Данке (использование стоп-слов в качестве диагностики языка пришло из той части моего разума, о которой я не знал;)
msw
5

На вашем примере это будет работать:

awk -v RS= -F '\n' -v OFS='\n' '{NF=NF/2+1;printf "%s", $0 RT}'

Детали

  • RS=, Устанавливает разделитель записей . Пустое значение - это особый случай, который означает, что запись является абзацем (последовательность строк, разделенных пустыми строками).
  • -F '\n': устанавливает разделитель полей ( поля в каждой записи являются строками).
  • OFS='\n': устанавливает разделитель выходного поля.

Для каждой записи (абзаца):

  • NF=1+NF/2(или NF=2(первые 2 строки) + (NF-2)/2(половина оставшихся строк)): измените количество полей, чтобы исключить английские.
  • printf "%s", $0 RT: печатает запись с последующим ограничителем записи (для восстановления одинакового расстояния между абзацами). Чтобы увидеть, что делает приведенный выше код, полезно, если вы добавите несколько операторов print в смесь. Что-то вроде этого:

Это предполагает окончания строки Unix. Если файл в формате MSDOS, как и файлы субтитров, необходимо предварительно обработать его с помощью d2uили dos2unix.

Стефан Шазелас
источник
Это предполагает, что английские линии всегда находятся на 3-й или 4-й позиции, верно?
СЛМ
2
@slm. Нет, эта половина строк - английская.
Стефан Шазелас
Глядя немного больше, это разбивает строки на записи. Затем вы просматриваете в каждой записи количество полей (NF). А НФ это линия в этом случае, верно? Я до сих пор не понимаю, что ты делаешь с NF-=NF/2-1битом. Вы рассчитываете, скажем, NF=4для первой записи, 714. Таким образом, вы получаете значения NF=4и NF/2-1=1, а затем вычитаете 1из NFоставленных вами 3? Затем печатать первые 3«поля» записи, отсюда выбрасывая 4-ю строку?
SLM
3

Ключевой частью этого подхода является доступ к хорошей базе данных английских слов. В моей системе есть этот файл, в /usr/share/dict/wordsкотором много слов, но вместо этого можно использовать другие источники.

Подходить

Мой общий подход заключается в следующем grep:

$ grep -vwf /usr/share/dict/words sample.txt

Где находится ваш пример вывода sample.txt.

В моем ограниченном тестировании размер wordsсловаря, казалось, застрял grep. В моей версии более 400 тысяч строк. Поэтому я начал делать что-то вроде этого, чтобы немного разбить это:

$ head -10000 /usr/share/dict/words > ~/10000words

Пробные прогоны (10 Кб)

Запустите ваш файл, используя первые 10 тысяч слов из «словаря».

$ grep -vwf ~/10000words sample.txt
714
01:11:22,267 --> 01:11:27,731
Auch wenn noch viele Generationen auf einen Wechsel hoffen,

715
01:11:27,732 --> 01:11:31,920
werde ich mein Bestes geben
und hoffe, dass andere das gleiche tun.
I'm giving mine, I'm doing my best
hoping the other will do the same

716
01:11:31,921 --> 01:11:36,278
Wir haben eine harte Arbeit vor uns, 
um den Lauf der Dinge zu ändern. 
it's going to be hard work
for things to turn around.

717
01:11:36,879 --> 01:11:42,881
Wenn man die Zentren künstlicher Besamung, 
die Zuchtlaboratorien und die modernen Kuhställe besichtigt, 
When visiting artificial insemination centers,
the selection center, modern stables,

ПРИМЕЧАНИЕ. Этот подход выполняется на моем ноутбуке i5 за 1,5 секунды.

Кажется, это жизнеспособный подход. Когда я увеличил его до 100 тыс. Строк, это заняло много времени, но я прервал его до его завершения, чтобы вы могли разбить wordsсловарь на несколько файлов.

ПРИМЕЧАНИЕ. Когда я сохранил 50 тыс. Строк, это заняло 32 секунды.

Дайвинг глубже (50 тыс. Строк)

Когда я начал расширять словарь до 50 тыс., Я столкнулся с проблемой, которой я боялся, пересечения между языками.

$ grep -vwf ~/50000words sample.txt
714
01:11:22,267 --> 01:11:27,731

715
01:11:27,732 --> 01:11:31,920
werde ich mein Bestes geben
und hoffe, dass andere das gleiche tun.
hoping the other will do the same

716
01:11:31,921 --> 01:11:36,278
Wir haben eine harte Arbeit vor uns, 
um den Lauf der Dinge zu ändern. 

717
01:11:36,879 --> 01:11:42,881
Wenn man die Zentren künstlicher Besamung, 
die Zuchtlaboratorien und die modernen Kuhställe besichtigt, 
the selection center, modern stables,

Анализируя проблему

Одна хорошая вещь с этим подходом состоит в том, что вы можете удалить -vи посмотреть, где перекрытие:

$ grep -wf ~/50000words sample.txt
Auch wenn noch viele Generationen auf einen Wechsel hoffen,
Even if it takes many generations hoping for a change,
I'm giving mine, I'm doing my best
it's going to be hard work
for things to turn around.
When visiting artificial insemination centers,

Слово, aufпо-видимому, на обоих языках ... ну, по крайней мере, оно в моем wordsфайле, так что это может быть метод проб и ошибок для уточнения списка слов по мере необходимости.

ПРИМЕЧАНИЕ: я знал, что это слово, aufпотому что grepзакрасил его красным, что не отображается в приведенном выше выводе из-за ограниченного характера SE 8-).

$ grep auf ~/50000words 
auf
aufait
aufgabe
aufklarung
auftakt
baufrey
Beaufert
beaufet
beaufin
Beauford
Beaufort
beaufort
bechauffeur
SLM
источник
Слово "auf" существует в английском языке? Это ДОЛЖНО быть ошибкой в ​​файле слов. Это определенно не так, по крайней мере, не автономно (это должен быть единственный путь, который здесь анализируется) в любом случае
syntaxerror
@syntaxerror - как я уже сказал, он находится в файле списка слов, который я использовал. Я разбираю автономно. Это то, что grep -wf ...делает. При лучшем предложении слов этот подход был бы более прямым. Другое решение (решение Стефана) зависит от структурируемых данных и не рассматривает их каким-либо контекстным образом, хотя подход msw кажется мне лучше.
SLM
Я предположил , что вы были разбор автономны. Как бы то ни было, я утверждаю, что если слово «auf» действительно является частью англоязычного списка слов, я хочу увидеть ссылку на словарь, где его существование задокументировано. Скорее всего, вы не найдете ни одного ... никогда. Но, как вы можете видеть, одно простое слово может создать полную путаницу в парсерах всех видов.
синтаксическая ошибка
@syntaxerror - извините за путаницу, я не согласился с вами по поводу того, что слово «auf» является реальным словом, просто это произошло в файле словаря, который я использовал. Между прочим, я дважды проверил происхождение этого файла, и он приходит из пакета на моем ноутбуке Fedora 14, который называется словами. Он использует этот URL как источник списков слов, которые он использует: en.wikipedia.org/wiki/Moby_Project
slm
1

Это похоже на .srtфайл. Если это так, и если количество английских строк в субтитре всегда совпадает с количеством немецких строк, то вы можете использовать:

awk 'BEGIN { RS="\r\n\r\n"; FS="\r\n"} {for (i=1;i<=(NF-2)/2+2; i++) print $i "\r"; print "\r"}' old.srt > new.srt

Где old.srtи где new.srtвы выбрали входные и выходные файлы.

wingedsubmariner
источник