【问题标题】:Speed up grep and writing to file加速 grep 和写入文件
【发布时间】:2020-12-07 05:15:04
【问题描述】:

我会感谢任何人的帮助。目前,我有 2 个文件(格式相同),每个文件都有超过 200 万行。以下文件示例:

文件 1:

00000001 YYYY
00000002 NYNN
00000003 YNYN
...
...

文件 2:

00000001 YYNY
00000002 NYNN
00000003 YNYN
...
...

所以请注意每个文件中的第一行是不同的,所以我将打印到文件 3:

00000001 YYYY

要完成上述过程,我有一个 bash 脚本:

  1. grep 文件 2 的前八个字符。
  2. 我将 grep 的回显/输出与文件 1 中的行进行比较。
  3. 如果它们不同,则将行(从文件 1)写入文件 3。

我想提供示例代码,但请记住,我只是动态编造的,但它的概念与我的脚本相同。目前,我 24 小时在线,只有 200 万在线 240k。我怎样才能以有效的方式加快速度?

input="file1"
while IFS= read -r line
do
LineFromFile1=$("${echo $line}")
firstEightChars=$("${echo $line:0:8}")
if grep -q "$firstEightChars" file2; then
  $LineFoundInFile2="$(grep $firstEightCharst file2)"
  if [[ $line == $LineFoundInFile2 ]]; then
    :
  else
    echo $line >> file3
done < "$input"

【问题讨论】:

  • 对两个文件进行排序,然后对它们进行比较 (n*log(n)) 比这种方法 (n^2) 更快。此外,您的示例将无法正确运行并且有多个拼写错误,并且每次匹配您 grep file2 两次。
  • 我想你想看看comm 命令。我从未使用过它,但手册页上说它用于“选择或拒绝两个文件共有的行”,这听起来像你想要的
  • join file1 file2 | egrep -v '( [^ ]*)\1' | cut -d' ' -f1-2 如果两个文件都在第一个字段上排序。
  • 两个文件的行数是否相同,两个文件的第一列是否完全相同?
  • @Cyrus 文件的行数不同,但第一列总是 8 个字符。

标签: linux bash


【解决方案1】:

使用 Python 脚本会如此简单

Python 有zip 函数,可以用来逐行读取和比较两个文件。

示例 Bash 脚本:

echo '00000001 YYYY
00000002 NYNN
00000003 YNYN' >file1


echo '00000001 YYNY
00000002 NYNN
00000003 YNYN' >file2

python3 -c '
with open("file1") as f_1, open("file2") as f_2:
   for t in zip(f_1, f_2):
      if t[0][8:-1] != t[1][8:-1]: print(t[0])'

打印:

00000001 YYYY

这里的优势(例如,相对于简单的awk 脚​​本)每个文件只有一行位于活动内存中 - 正在比较的两行。

但是,Unix 对所描述的问题有其他解决方案。你也可以使用pasteawk

paste file1 file2 | awk '$2!=$4 {print $1 OFS $2}'

或者如果第一列的数字作为索引,你可以使用join和awk:

join file1 file2 | awk '$2!=$3 {print $1 OFS $2}'

或者comm 命令(抑制第 1 列和第 3 列)如果每个文件中的第 1 列已排序也可以:

comm -1 -3 file1 file2

所有三个 Unix/Linux 命令/管道产生:

00000001 YYYY

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-25
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2013-01-20
    • 2017-06-10
    相关资源
    最近更新 更多