【问题标题】:remove latin-1 character from large text file in bash从 bash 中的大文本文件中删除 latin-1 字符
【发布时间】:2018-09-19 13:48:14
【问题描述】:

我有一些大型数据集纯文本文件(维基百科文章),我必须像这里一样删除 latin-1 字符:

 kemer } şehir kır toplam }}
use specific terminology . for example , it is often more appropriate for people or things from ethiopia ( a country in africa ) to be described as ethiopian , not carelessly ( with the risk of stereotyping ) as african . 
 bat avg . 
 label ਕਾਲਜ
 ਅਡੋਲਫ ਹਿਟਲਰ ਨੇ ਦੇਸ਼ ਵਿਚ ਕਮਿਊਨਿਸਟ ਪਾਰਟੀ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਤੋਂ ਨਾਂਹ ਕਰ ਦਿਤੀ।
 alt }
        if not extra_units then
 utc_offset + 
 ਕਬਜਾ ( ) 
 demographics _title regional

我只想得到喜欢

ਕਾਲਜ
 ਅਡੋਲਫ ਹਿਟਲਰ ਨੇ ਦੇਸ਼ ਵਿਚ ਕਮਿਊਨਿਸਟ ਪਾਰਟੀ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਤੋਂ ਨਾਂਹ ਕਰ ਦਿਤੀ।

 ਕਬਜਾ

并最终修剪琐碎的空白行。 我使用的方法如下

<?php
$in = fopen('php://stdin','rb');
while($line = stream_get_line($in, 64000)) {
    foreach(str_split($line) as $char) {
        $ordChar = ord($char);
        if($ordChar > 127 || $ordChar <= 31) {
            echo $char;
        }
    }
}

像cat wiki.hi.txt | php -d memory_limit=1024M escape_latin.php &gt; wiki.hi.esc.txt一样使用

这种方法可以正常工作,唯一的问题是随着文件大小的增长,性能会变得最差,正如我在正在处理的文件上看到的 watch du -h filename 所见。我很惊讶,因为我在本地磁盘上工作并且我正在使用stream_get_line 来获取流式传输中的行。

我在 python 中尝试过相同的方法,但在文件大小约为 1GB 时我得到了几乎相同的性能。

更多详情请参阅here。

[更新] 我在这里报告一些建议的替代方法的结果

使用regex 方法,这似乎产生了几乎相同的输出文件:

一个 ~50MB 文件

$ time tr -d "[:alnum:][:punct:]" < wiki.as.txt > wiki.as.test.txt

real    0m2.990s
user    0m2.818s
sys 0m0.088s

一个 ~100MB 文件

$ time tr -d "[:alnum:][:punct:]" < wiki.gu.txt > wiki.gu.test.txt

real    0m7.322s
user    0m6.772s
sys 0m0.282s

一个 ~600MB 文件

$ time tr -d "[:alnum:][:punct:]" < wiki.ta.txt > wiki.ta.test.txt

real    0m35.973s
user    0m33.498s
sys 0m1.254s

一个 ~1000MB (1GB) 文件

$ time tr -d "[:alnum:][:punct:]" < wiki.ja.1.txt > wiki.ja.1.test.txt

real    1m5.409s
user    1m0.669s
sys 0m2.068s

【问题讨论】:

    标签: utf-8 dataset iso-8859-1


    【解决方案1】:

    试试正则表达式。

    如果您是从 CLI 运行它,请尝试类似

    tr -d "[:alnum:][:punct:]" < wiki.hi.txt > wiki.hi.esc.txt
    

    如果你喜欢在 php 中做同样的事情 -

    <?php
    $in = fopen('php://stdin','rb');
    while($line = stream_get_line($in, 64000)) {
        echo preg_replace('/[:alnum:][:punct:]/', '', $line);        
    }
    

    但是请检查这些以确保他们正在做你想要的 - 特别是。 php,因为我在这里没有测试设置。它可能存在语法问题和/或更糟。运气好的话,有人会编辑它或提供更好的解决方案,或者至少评论并指出我可能做错了什么。

    希望对你有帮助。

    【讨论】:

    • 谢谢,我正在尝试最简单的正则表达式方法。结果文件似乎没问题。对于不同文件大小的表现,我更新了上面的问题。看起来很有希望。
    • 酷。很高兴它有帮助。接受解决方案?
    猜你喜欢
    • 2022-09-27
    • 2019-12-03
    • 2023-04-08
    • 2012-04-27
    • 2018-11-20
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    相关资源
    最近更新 更多