首页 > 解决方案 > 加速 grep 和写入文件

问题描述

我会很感激任何人的帮助。目前,我有 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"

标签: linuxbash

解决方案


使用 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 对所描述的问题有其他解决方案。您还可以使用粘贴awk

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

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

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

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

comm -1 -3 file1 file2

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

00000001 YYYY

推荐阅读