如何删除文本文件中的所有英文行?


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
您可以安全地假设每种语言的行数总是相同吗?如果有两条德语行,总会有两条英文行等吗?
terdon

Answers:


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, 

稍完整的版本在单词中时应忽略各种标点符号,例如,.英语撇号',但不能忽略。通过查找英语中从未出现过的代码点(例如«ßü),可以获得更高的准确性,但这留给读者练习。


非常好的方法。比我的砍砍法好得多8
slm

Danke(使用停用词作为一种语言的诊断来自我不知道在那里的一部分;)
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(前两行)+ (NF-2)/2(剩余的一半)):更改字段数以排除英文字段。
  • printf "%s", $0 RT:打印记录,后跟记录终止符(以恢复段落之间相同的间距)。如果将一些打印语句添加到混合中,以查看上面的代码在做什么,这将很有帮助。像这样:

假定Unix行结尾。如果文件是字幕文件中常见的MSDOS格式,则需要使用d2u或对其进行预处理dos2unix


假设英语行始终处于第3或第4位,对不对?
slm

2
@slm。不,那一半的线是英语。
斯特凡Chazelas

再看一点,这会将行划分为记录。然后,您在每个记录中查找字段数(NF)。在这种情况下,NF是一条线,对吗?我还是不明白你在做什么NF-=NF/2-1。您是否要NF=4对第一个记录714进行说说。因此,您得到了NF=4和的值NF/2-1=1,然后1NF剩下的减去3?然后打印记录的第一个3“字段”,因此删除第4行?
slm

3

这种方法的关键是可以访问良好的英语单词数据库。我的系统上有此文件,/usr/share/dict/words其中包含很多单词,但可以使用其他来源代替。

方法

我的一般方法是这样使用grep

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

您的示例输出在的位置sample.txt

在我有限的测试中,words字典的大小似乎很小grep。我的版本中有40万多行。所以我开始做这样的事情来分解它:

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

样品运行(10k)

通过使用“字典”中的第一个10k单词来运行文件。

$ 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秒。

这似乎是一种可行的方法。当我将其增加到10万行时,它开始花了很长时间,但是在完成之前我中止了它,因此您可以将words字典分成几个文件。

注意:当我将其备份到50k行时,花费了32秒。

潜水更深(5万行)

当我开始将字典扩展到50k时,我遇到了我担心的问题,即两种语言之间的重叠。

$ 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

英语中存在单词“ auf”吗?那一定是Word文件中的错误。无论如何,它绝对不是,至少不是独立的(这应该是这里解析的唯一方法)
语法错误

@syntaxerror-正如我所说的,它在我使用的单词列表文件中。我正在独立分析。那就是这样grep -wf ...做的。有了更好的措词,这种方法将更加直接。其他解决方案(Stephane的解决方案)取决于正在构造的数据,并且不以任何上下文方式查看数据,但对我来说,msw的方法似乎有更好的优势。
slm

我以为您独立解析的。无论如何,我确认如果单词“ auf”确实是英语单词列表的一部分,我想查看字典引用中记录了它的存在的地方。很可能,您永远找不到...。但是,正如您所看到的,一个单词可能在各种解析器中造成完全混乱。
语法错误

@syntaxerror-抱歉,我并没有与您不同意“ auf”是一个实际的词,只是它恰好在我使用的字典文件中。顺便说一句,我仔细检查了该文件的沿袭,它来自我Fedora 14笔记本电脑上一个叫做word的软件包。它将此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.srtnew.srt在您选择的输入和输出文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.