【问题标题】:Merging files in Linux在 Linux 中合并文件
【发布时间】:2012-07-22 05:42:36
【问题描述】:

我正在使用 Cygwin 合并多个文件。但是,我想知道我的方法是否正确。这既是一个问题,也是一个讨论:)

首先,关于我拥有的文件的一些信息:

  1. 这两个文件都有 ASCII 和非 ASCII 字符。
  2. File1 中有 7899097 行,大小约为 70.9 Mb
  3. File2 中有 14344391 行,大小约为 136.6 Mb

文件编码信息:

$ file -bi file1.txt
text/x-c++; charset=unknown-8bit

$ file -bi file2.txt
text/x-c++; charset=utf-8

$ file -bi output.txt
text/x-c++; charset=unknown-8bit

这是我合并两个文件的方法,对它们进行排序,然后删除所有重复的条目:

  1. 我创建了一个临时文件夹并将两个文本文件都放入其中。
  2. 我运行以下命令来合并两个文件,但在两者之间保留一个换行符

    for file in *.txt; do
        cat $file >> output.txt
        echo >> output.txt
    done
    

生成的 output.txt 文件中有 22243490 行,大小为 207.5 Mb

现在,如果我在其上运行如下所示的排序命令,我会收到一个错误,因为其中存在非 ASCII 字符(可能是 unicode,宽字符):

sort -u output.txt
string comparison failed: Invalid or incomplete multibyte or wide character

所以,我将环境变量LC_ALL设置为C,然后运行命令如下:

cat output.txt | sort -u | uniq >> result.txt

而且,result.txt 中有 22243488 行,大小为 207.5 Mb。

所以,result.txt 和 output.txt 一样

现在,我已经知道 output.txt 中有很多重复条目,那么为什么上面的命令无法删除重复条目?

另外,考虑到文件的大小,我想知道这是否是一种有效的方法来合并多个文件,对它们进行排序,然后将它们唯一化?

【问题讨论】:

  • 是否可以将您的问题总结为 - 能够对多字节字符数据文件进行排序和合并?文件是否设置为 UTF-8 编码(BOM 设置是否正确?)
  • 我已经编辑了帖子并指定了文件编码格式。不,问题不只是关于排序和合并,我已经给出了一些我想知道的具体细节。是的,排序、合并和删除重复项也是我想知道的。

标签: uniq


【解决方案1】:

嗯,我会用

cat file1.txt file2.txt other-files.* | recode enc1..enc2 | sort | uniq > file3.txt 

但要小心 - 这可能会导致一些大文件大小出现问题,以千兆字节(或更大)计算,无论如何,数百兆字节应该没问题。如果我想要真正的效率,例如拥有非常大的文件,我首先删除单个文件重复项,然后对其进行排序,一个接一个地合并,然后再次排序并再次删除重复的行。理论上 uniq -c 和 grep 过滤器可以删除重复项。尽量避免陷入一些不必要的复杂解决方案:)

http://catb.org/~esr/writings/unix-koans/two_paths.html

编辑:

mv file1.txt file1_iso1234.txt 
mv file2.txt file2_latin7.txt
ls file*.txt |while read line; do cat $line |recode $(echo $line|cut -d'_' -f2 |cut -d'.' -f1)..utf8 ; done | sort | uniq > finalfile.txt

【讨论】:

  • 好的,谢谢。就我而言,这两个文件的编码都存在问题。那么,我将如何使用重新编码选项?你能详细说明一下吗?此外,我的命令看起来和你的一模一样,但仍然没有删除重复项,可能是什么原因?
  • 当然你需要在 uniq 之前排序,并且在排序之前你需要所有输入都具有相同的编码。因此,如果文件具有不同的编码,您需要将其从适当的编码重新编码为您决定使用的一些常见编码,可能是 utf8。为了快速解决它,您可以重命名文件以包含文件名 mv file1.txt file1_iso1234.txt mv file2.txt file2_latin7.txt 中的编码,然后例如ls file*.txt |while 读取行; do cat $line |recode $(echo $line|cut -d'_' -f2 |cut -d'.' -f1)..utf8 | .. [在带有排序、uniq 等的管道之后以此类推] 类似的东西..
  • 谢谢。但是,重新编码在 Cygwin 中不可用。不过,我已经了解您的解决方案。我尝试将 iconv 从 us_ascii 编码转换为 utf-8 并在解析原始文件时出错。我也会试试你的解决方案。
猜你喜欢
  • 2017-09-14
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 2011-02-04
  • 2015-04-01
  • 2020-09-18
相关资源
最近更新 更多