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

jes*_*sta 9 awk gawk

我正在处理一个相当大的推文集合,我想为每条推文获取其提及(其他用户的名字,前缀为一个@),如果提到的用户也在文件中:

users = new Dictionary()
for each line in file:
   username = get_username(line)
   userid   = get_userid(line)
   users.add(key = userid, value = username)
for each line in file:
   mentioned_names = get_mentioned_names(line)
   mentioned_ids = mentioned_names.map(x => if x in users: users[x] else null)
   print "$line | $mentioned_ids"
Run Code Online (Sandbox Code Playgroud)

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

我可以用非常黑客的方式做到这一点(比如cat'将文件sed复制两次,将其传递给每个文件中的所有行添加不同的前缀cat),但我希望能在几个月内理解这些代码讨厌自己

AWK的做法是什么?

PD:

我找到的不那么可怕的方式:

function rewind(    i)
{
    # from https://www.gnu.org/software/gawk/manual/html_node/Rewind-Function.html
    # shift remaining arguments up
    for (i = ARGC; i > ARGIND; i--)
        ARGV[i] = ARGV[i-1]

    # make sure gawk knows to keep going
    ARGC++

    # make current file next to get done
    ARGV[ARGIND+1] = FILENAME

    # do it
    nextfile
}

BEGIN {
 count = 1;
}

count == 1 {
 # first pass, fills an associative array
}

count == 2 {
 # second pass, uses the array
}

FNR == 30 { 
   # handcoded length, horrible
   # could also be automated calling wc -l, passing as parameter
  if (count == 1) {
        count = 2;
        rewind(1)
    }
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*ech 15

在awk中处理两个单独文件或两次相同文件的惯用方法是这样的:

awk 'NR==FNR{ 
    # fill associative array 
    next
}
{
    # use the array
}' file1 file2
Run Code Online (Sandbox Code Playgroud)

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