AWK:两次完成文件,执行不同的任务

前端之家收集整理的这篇文章主要介绍了AWK:两次完成文件,执行不同的任务前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在处理一个相当大的推文集合,我想为每个推文获取其提及(其他用户的名字,前缀为@),如果提到的用户也在文件中:
  1. users = new Dictionary()
  2. for each line in file:
  3. username = get_username(line)
  4. userid = get_userid(line)
  5. users.add(key = userid,value = username)
  6. for each line in file:
  7. mentioned_names = get_mentioned_names(line)
  8. mentioned_ids = mentioned_names.map(x => if x in users: users[x] else null)
  9. print "$line | $mentioned_ids"

我已经使用GAWK处理该文件了,所以不是在Python或C中再次处理它,我决定尝试将其添加到我的AWK脚本中.但是,我无法找到一种方法来传递相同的文件,为每个文件执行不同的代码.大多数解决方案都意味着多次调用AWK,但后来我放弃了我在第一遍中创建的关联数组.

我可以用很笨拙的方式做到这一点(比如把文件夹到两次,然后通过sed传递给每只猫的所有行添加不同的前缀),但我希望能够在一对夫妇中理解这段代码.几个月没有恨自己.

什么是AWK方式来做到这一点?

PD:

我找到的不太可怕的方式:

  1. function rewind( i)
  2. {
  3. # from https://www.gnu.org/software/gawk/manual/html_node/Rewind-Function.html
  4. # shift remaining arguments up
  5. for (i = ARGC; i > ARGIND; i--)
  6. ARGV[i] = ARGV[i-1]
  7.  
  8. # make sure gawk knows to keep going
  9. ARGC++
  10.  
  11. # make current file next to get done
  12. ARGV[ARGIND+1] = FILENAME
  13.  
  14. # do it
  15. nextfile
  16. }
  17.  
  18. BEGIN {
  19. count = 1;
  20. }
  21.  
  22. count == 1 {
  23. # first pass,fills an associative array
  24. }
  25.  
  26. count == 2 {
  27. # second pass,uses the array
  28. }
  29.  
  30. FNR == 30 {
  31. # handcoded length,horrible
  32. # could also be automated calling wc -l,passing as parameter
  33. if (count == 1) {
  34. count = 2;
  35. rewind(1)
  36. }
  37. }

解决方法

在awk中处理两个单独文件或两次相同文件的惯用方法是这样的:
  1. awk 'NR==FNR{
  2. # fill associative array
  3. next
  4. }
  5. {
  6. # use the array
  7. }' file1 file2

总记录数NR仅等于第一个文件上当前文件FNR的记录号. next跳过第一个文件的第二个块.然后为第二个文件处理第二个块.如果file1和file2是同一个文件,那么这会两次传递该文件.

猜你在找的Linux相关文章