读取文件并查找所有出现的地方,并为出现的地方之间的内容生成哈希值

读取文件并查找所有出现的地方,并为出现的地方之间的内容生成哈希值

我有一个这样的文件:

1   Record|1111|ABC
2   text in between for record 1
3   text in between for record 1
4   Record|2222|XYZ
5   text in between for record 2    
6   Record|3333|XYZ
7   text in between for record 3
8   .

我想读取这个文件并生成类似的东西

<Record_number> | <start line> | <number of lines> | md5sum(content)

那是:

1111|1|2|md5sum(Record|1111|ABC\ntext in between for record 1\ntext in between for record 1)
2222|4|1|md5sum(Record|2222|XYZ\ntext in between for record 2\n)

ETC。

目前,我正在使用两步过程来执行此操作:

步骤1:

grep -n -C 0 "Record|" ../test.txt | awk -F[':|'] '{print $3"|"$1}'

将创造

1111|1
2222|4
3333|6

第2步: 逐行读取这个文件并通过脚本生成md5sum和行数。

这两个步骤处理的问题是需要更多的处理时间,并且文件大小很大(~4GB)。

有一个更好的方法吗?

答案1

大部分都可以是

awk -F"|" -v OFS="|" '
function md5(lines){
  func="printf \"%s\" \""lines"\"|md5sum|cut -f1 -d\ " ;
  func | getline v;
  return v
}
/Record/{
  if(s>0)
    print r,l,c,md5(line);
  s=1;
  r=$2;
  c=1;
  l=NR;
  line=$0
}
!/Record/{
  line=line"\n"$0;
  c+=1
}
END{
  print r,l,c,md5(line);
}' file

简单代码解释:

  1. 将字段分隔符(输入和输出)更改为|

  2. 分配md5函数(感谢皮埃尔·奥利维尔·瓦雷斯对于想法)计算适当的输入行的 md5sum。 (也许有更好的方法,欢迎您发表评论)

  3. 对于包含Record单词的行,将必要的字段放入变量中,并将计数器中断为 1,并从单词第二次出现开始打印上一个格式化行Record(对于第二次打印第一次,对于第三次打印第二次,依此类推)。

  4. 对于没有Record单词的行,只需将自己添加到line变量中,并将 1 添加到计数器中c

  5. 完成后打印最后格式化的行(因为最后一行存储在内存中,并且应该在遇到下一个Record单词但已到达文件结尾时打印)

答案2

基于科斯塔斯的回答。

1)创建一个文件parse.awk,内容如下:

/^Record/ {
  if (s>0) {
    printf ("%s|%s|", r,l)
    system("echo '"line"' | md5sum - | awk '{print $1}' ");
  }
  s=1;
  r=$2;
  c=1;
  l=NR;
  line="$0";
}
!/^Record/ {
  line=line"\n""$0";
  c+=1
}
END {
  printf ("%s|%s|", r,l)
  system("echo '"line"' | md5sum - | awk '{print $1}' ");
}

参见科斯塔斯的解释。该脚本只是执行 printf结果行的开头(而不是打印,即放置换行符) system(echo $line | md5sum)来打印 md5 - 和换行符

2) 运行awk -F"|" -f parse.awk myfile

3)享受结果:

1111|1|cb36533781d8dd00011a85b0db9b87b3
2222|4|521331bb249e8a668afa2199fa8d289a
3333|6|6c2564464187094e9db3159d26ade2a5

相关内容