使用 awk 使用来自行和列的信息生成新行
Generating new rows using information from rows and columns with awk
我有一个文件,其中输入的格式在输入代码中如下所述。 "word" "frq" 和 "word_meanings" 将对应于第 1、2 和 3 列。第 1 列中有单词,第 2 列中有数字,第 3 列中有含义字。我想将第 3 列中的含义相互配对,以便在输出中它们在同一行中,如果它们对第 1 列具有相同的 "word"。我还想使用 [=21= 中的数字] 列来决定这些含义如何相互配对。
输入:
word frq word_meanings
door 12 meaning_a
door 25 meaning_b
door 3 meaning_c
hand 20 meaning_d
hand 17 meaning_e
floor 4 meaning_f
floor 30 meaning_g
floor 20 meaning_h
floor 4 meaning_e
输出类似于
door meaning_b meaning_a
door meaning_b meaning_c
hand meaning_d meaning_e
floor meaning_g meaning_h
floor meaning_g meaning_e
floor meaning_g meaning_f
解释一下,因为'meaning_b'的frq值为25,所以在所有以door开头的列中frq值最高,所以用'meaning_b'来创建与其他行中的其他含义配对,其中门作为第一列的词。
通过两次遍历文件,您可以使用第一次收集频率最高的含义,第二次打印出具有这些含义的每一行。
在 awk 中执行此操作的标准方法是使用 NR
和 FNR
。当NR == FNR
(当前总记录数等于当前文件内的记录数)时,您知道您是第一次处理该文件。通过以 next
语句结束该块,您可以跳过后面的操作并直接读取文件的下一行。
如果您到达第二个操作块,您知道您正在第二次读取文件,您可以在其中打印每一行的结果。
别忘了在 awk 命令行中传递文件两次!每次通过一次。
此技术适用于所有类型的 "join" 应用程序(在本例中为自连接)。
$ cat words.txt
door 12 meaning_a
door 25 meaning_b
door 3 meaning_c
hand 20 meaning_d
hand 17 meaning_e
floor 4 meaning_f
floor 30 meaning_g
floor 20 meaning_h
floor 4 meaning_e
$ cat words.awk
NR == FNR {
# first pass, build array of meanings with max freq
if (max_frq[] < ) {
max_frq[] = ;
max_meaning[] = ;
}
next;
}
{
# second pass, print words and meanings with those collected in first pass
if (max_meaning[] != ) {
print , max_meaning[], ;
}
}
$ awk -f words.awk words.txt words.txt
door meaning_b meaning_a
door meaning_b meaning_c
hand meaning_d meaning_e
floor meaning_g meaning_f
floor meaning_g meaning_h
floor meaning_g meaning_e
编辑
要更改输出分隔符,您可以在命令行上设置 OFS
:
$ awk -v OFS=, -f words.awk words.txt words.txt
door,meaning_b,meaning_a
door,meaning_b,meaning_c
hand,meaning_d,meaning_e
floor,meaning_g,meaning_f
floor,meaning_g,meaning_h
floor,meaning_g,meaning_e
按word和frq排序,然后让awk
处理细节:
sort -k1,1 -k2,2nr |
awk ' != word {word = ; means = } means != {print word, means, }'
输出:
door meaning_b meaning_a
door meaning_b meaning_c
floor meaning_g meaning_h
floor meaning_g meaning_e
floor meaning_g meaning_f
hand meaning_d meaning_e
我有一个文件,其中输入的格式在输入代码中如下所述。 "word" "frq" 和 "word_meanings" 将对应于第 1、2 和 3 列。第 1 列中有单词,第 2 列中有数字,第 3 列中有含义字。我想将第 3 列中的含义相互配对,以便在输出中它们在同一行中,如果它们对第 1 列具有相同的 "word"。我还想使用 [=21= 中的数字] 列来决定这些含义如何相互配对。
输入:
word frq word_meanings
door 12 meaning_a
door 25 meaning_b
door 3 meaning_c
hand 20 meaning_d
hand 17 meaning_e
floor 4 meaning_f
floor 30 meaning_g
floor 20 meaning_h
floor 4 meaning_e
输出类似于
door meaning_b meaning_a
door meaning_b meaning_c
hand meaning_d meaning_e
floor meaning_g meaning_h
floor meaning_g meaning_e
floor meaning_g meaning_f
解释一下,因为'meaning_b'的frq值为25,所以在所有以door开头的列中frq值最高,所以用'meaning_b'来创建与其他行中的其他含义配对,其中门作为第一列的词。
通过两次遍历文件,您可以使用第一次收集频率最高的含义,第二次打印出具有这些含义的每一行。
在 awk 中执行此操作的标准方法是使用 NR
和 FNR
。当NR == FNR
(当前总记录数等于当前文件内的记录数)时,您知道您是第一次处理该文件。通过以 next
语句结束该块,您可以跳过后面的操作并直接读取文件的下一行。
如果您到达第二个操作块,您知道您正在第二次读取文件,您可以在其中打印每一行的结果。
别忘了在 awk 命令行中传递文件两次!每次通过一次。
此技术适用于所有类型的 "join" 应用程序(在本例中为自连接)。
$ cat words.txt
door 12 meaning_a
door 25 meaning_b
door 3 meaning_c
hand 20 meaning_d
hand 17 meaning_e
floor 4 meaning_f
floor 30 meaning_g
floor 20 meaning_h
floor 4 meaning_e
$ cat words.awk
NR == FNR {
# first pass, build array of meanings with max freq
if (max_frq[] < ) {
max_frq[] = ;
max_meaning[] = ;
}
next;
}
{
# second pass, print words and meanings with those collected in first pass
if (max_meaning[] != ) {
print , max_meaning[], ;
}
}
$ awk -f words.awk words.txt words.txt
door meaning_b meaning_a
door meaning_b meaning_c
hand meaning_d meaning_e
floor meaning_g meaning_f
floor meaning_g meaning_h
floor meaning_g meaning_e
编辑
要更改输出分隔符,您可以在命令行上设置 OFS
:
$ awk -v OFS=, -f words.awk words.txt words.txt
door,meaning_b,meaning_a
door,meaning_b,meaning_c
hand,meaning_d,meaning_e
floor,meaning_g,meaning_f
floor,meaning_g,meaning_h
floor,meaning_g,meaning_e
按word和frq排序,然后让awk
处理细节:
sort -k1,1 -k2,2nr |
awk ' != word {word = ; means = } means != {print word, means, }'
输出:
door meaning_b meaning_a
door meaning_b meaning_c
floor meaning_g meaning_h
floor meaning_g meaning_e
floor meaning_g meaning_f
hand meaning_d meaning_e