Bash - word/term 每行的频率(即文档)
Bash - word/term frequency per line (i.e. document)
我有一个这样的文件rev.txt
:
header1,header2
1, some text here
2, some more text here
3, text and more text here
我还有一个词汇文档,其中包含来自 rev.txt
的所有唯一单词,就像这样(但已排序):
a
word
list
text
here
some
more
and
我想为 rev.txt
中的每一行生成词频 table,其中列出了每个词汇表单词在 rev.txt
的每一行中的出现次数,如下所示:
0 0 0 1 1 1 0 0
0 0 0 1 1 1 1 0
0 0 0 2 1 0 1 1
它们也可以用逗号分隔。
这类似于 a question here。但是,我不想搜索整个文档,而是想逐行搜索,使用我已有的完整词汇表。
回复:让-弗朗索瓦·法布尔
实际上,我正在 MATLAB 中执行这些操作。但是,bash(我相信)对于这种预处理会更快,因为我可以直接访问文件的磁盘。
通常我会使用python,但是限制自己使用bash,这个hacky one-liner 解决方案将适用于给定的测试用例。
perl -pe 's|^.*?,[ ]?(.*)||' rev.txt | sed '1d' | awk -F' ' 'FILENAME=="wordlist.txt" {wc[]=0; wl[wllen++]=; next}; {for(i=1; i<=NF; i++){wc[$i]++}; for(i=0; i<wllen; i++){print wc[wl[i]]" "; wc[wl[i]]=0; if(i+1==wllen){print "\n"} }}' ORS="" wordlist.txt -
Explanation/My 想...
在第一部分中,perl -pe 's|^.*?,[ ]?(.*)||' rev.txt
用于从 "rev.txt".
中提取第一个逗号后的所有内容(+删除前导白色space)
在下一部分中,sed '1d'
用于删除第一行,即 header 行。
在接下来的部分中,我们指定awk -F' ' ... ORS="" wordlist.txt -
使用白色space作为字段分隔符,输出记录分隔符为无space(注意:我们将打印它们go),并从 wordlist.txt(即 "vocabulary document with all unique words from rev.txt")和标准输入读取输入。
在 awk 命令中,如果 FILENAME 等于 "wordlist.txt",则 (1) 初始化数组 wc
,其中键为词汇,计数为 0,以及 (2)初始化一个列表 wl
,其中单词顺序与 wordlist.txt.
相同
FILENAME=="wordlist.txt" {
wc[]=0;
wl[wllen++]=;
next
};
初始化后,对于标准输入一行中的每个单词(即整洁的rev.txt),增加wc
中单词的计数。
{ for (i=1; i<=NF; i++) {
wc[$i]++
};
为一行添加字数后,对于字列表wl
中的每个字,用白色打印该字的字数space并在wc
回到 0。如果单词是列表中的最后一个,则在输出中添加白色 space。
for (i=0; i<wllen; i++) {
print wc[wl[i]]" ";
wc[wl[i]]=0;
if(i+1==wllen){
print "\n"
}
}
}
总的来说,这应该会产生指定的输出。
这是 awk 中的一个。它读取词汇文件voc.txt
(在awk中自动生成它是小菜一碟),为每一行文本复制单词列表并计算单词频率:
$ cat program.awk
BEGIN {
PROCINFO["sorted_in"]="@ind_str_asc" # order for copying vocabulary array w
}
NR==FNR { # store the voc.txt to w
w[]=0
next
}
FNR>1 { # process text files to matrix
for(i in w) # copy voc array
a[i]=0
for(i=2; i<=NF; i++) # count freqs
a[$i]++
for(i in a) # output matrix row
printf "%s%s", a[i], OFS
print ""
}
运行它:
$ awk -f program.awk voc.txt rev.txt
0 0 1 0 0 1 1 0
0 0 1 0 1 1 1 0
0 1 1 0 1 0 2 0
我有一个这样的文件rev.txt
:
header1,header2
1, some text here
2, some more text here
3, text and more text here
我还有一个词汇文档,其中包含来自 rev.txt
的所有唯一单词,就像这样(但已排序):
a
word
list
text
here
some
more
and
我想为 rev.txt
中的每一行生成词频 table,其中列出了每个词汇表单词在 rev.txt
的每一行中的出现次数,如下所示:
0 0 0 1 1 1 0 0
0 0 0 1 1 1 1 0
0 0 0 2 1 0 1 1
它们也可以用逗号分隔。
这类似于 a question here。但是,我不想搜索整个文档,而是想逐行搜索,使用我已有的完整词汇表。
回复:让-弗朗索瓦·法布尔
实际上,我正在 MATLAB 中执行这些操作。但是,bash(我相信)对于这种预处理会更快,因为我可以直接访问文件的磁盘。
通常我会使用python,但是限制自己使用bash,这个hacky one-liner 解决方案将适用于给定的测试用例。
perl -pe 's|^.*?,[ ]?(.*)||' rev.txt | sed '1d' | awk -F' ' 'FILENAME=="wordlist.txt" {wc[]=0; wl[wllen++]=; next}; {for(i=1; i<=NF; i++){wc[$i]++}; for(i=0; i<wllen; i++){print wc[wl[i]]" "; wc[wl[i]]=0; if(i+1==wllen){print "\n"} }}' ORS="" wordlist.txt -
Explanation/My 想...
在第一部分中,perl -pe 's|^.*?,[ ]?(.*)||' rev.txt
用于从 "rev.txt".
在下一部分中,sed '1d'
用于删除第一行,即 header 行。
在接下来的部分中,我们指定awk -F' ' ... ORS="" wordlist.txt -
使用白色space作为字段分隔符,输出记录分隔符为无space(注意:我们将打印它们go),并从 wordlist.txt(即 "vocabulary document with all unique words from rev.txt")和标准输入读取输入。
在 awk 命令中,如果 FILENAME 等于 "wordlist.txt",则 (1) 初始化数组 wc
,其中键为词汇,计数为 0,以及 (2)初始化一个列表 wl
,其中单词顺序与 wordlist.txt.
FILENAME=="wordlist.txt" {
wc[]=0;
wl[wllen++]=;
next
};
初始化后,对于标准输入一行中的每个单词(即整洁的rev.txt),增加wc
中单词的计数。
{ for (i=1; i<=NF; i++) {
wc[$i]++
};
为一行添加字数后,对于字列表wl
中的每个字,用白色打印该字的字数space并在wc
回到 0。如果单词是列表中的最后一个,则在输出中添加白色 space。
for (i=0; i<wllen; i++) {
print wc[wl[i]]" ";
wc[wl[i]]=0;
if(i+1==wllen){
print "\n"
}
}
}
总的来说,这应该会产生指定的输出。
这是 awk 中的一个。它读取词汇文件voc.txt
(在awk中自动生成它是小菜一碟),为每一行文本复制单词列表并计算单词频率:
$ cat program.awk
BEGIN {
PROCINFO["sorted_in"]="@ind_str_asc" # order for copying vocabulary array w
}
NR==FNR { # store the voc.txt to w
w[]=0
next
}
FNR>1 { # process text files to matrix
for(i in w) # copy voc array
a[i]=0
for(i=2; i<=NF; i++) # count freqs
a[$i]++
for(i in a) # output matrix row
printf "%s%s", a[i], OFS
print ""
}
运行它:
$ awk -f program.awk voc.txt rev.txt
0 0 1 0 0 1 1 0
0 0 1 0 1 1 1 0
0 1 1 0 1 0 2 0