sfa*_*tor 89 bash command-line frequency
我有多个列分隔的制表符分隔文件.我想计算文件夹中所有文件的列中不同值的出现频率,并按递减顺序对它们进行排序(最高计数优先).如何在Linux命令行环境中完成此操作?
它可以使用任何常见的命令行语言,如awk,perl,python等.
Pau*_*ce. 144
要查看第二列的频率计数(例如):
awk -F '\t' '{print $2}' * | sort | uniq -c | sort -nr
Run Code Online (Sandbox Code Playgroud)
fileA.txt
z z a
a b c
w d e
Run Code Online (Sandbox Code Playgroud)
fileB.txt
t r e
z d a
a g c
Run Code Online (Sandbox Code Playgroud)
fileC.txt
z r a
v d c
a m c
Run Code Online (Sandbox Code Playgroud)
结果:
3 d
2 r
1 z
1 m
1 g
1 b
Run Code Online (Sandbox Code Playgroud)
The*_*ard 66
这是在shell中执行此操作的方法:
FIELD=2
cut -f $FIELD * | sort| uniq -c |sort -nr
Run Code Online (Sandbox Code Playgroud)
这就是bash擅长的事情.
在GNU网站表明这个漂亮的awk脚本,它打印两个单词和它们的频率.
可能的变化:
sort -nr
(和反向word
和freq[word]
)看到的结果降序排列.freq[3]++
- 用列号替换3.开始:
# wordfreq.awk --- print list of word frequencies
{
$0 = tolower($0) # remove case distinctions
# remove punctuation
gsub(/[^[:alnum:]_[:blank:]]/, "", $0)
for (i = 1; i <= NF; i++)
freq[$i]++
}
END {
for (word in freq)
printf "%s\t%d\n", word, freq[word]
}
Run Code Online (Sandbox Code Playgroud)
这段代码计算所有列的出现情况,并为每个列打印排序的报告:
# columnvalues.pl
while (<>) {
@Fields = split /\s+/;
for $i ( 0 .. $#Fields ) {
$result[$i]{$Fields[$i]}++
};
}
for $j ( 0 .. $#result ) {
print "column $j:\n";
@values = keys %{$result[$j]};
@sorted = sort { $result[$j]{$b} <=> $result[$j]{$a} || $a cmp $b } @values;
for $k ( @sorted ) {
print " $k $result[$j]{$k}\n"
}
}
Run Code Online (Sandbox Code Playgroud)
将文本另存为columnvalues.pl
。 perl columnvalues.pl files*
在顶层的while循环中:
*循环合并的输入文件的每一行
*将行拆分为@Fields数组
*对于每一列,请增加结果哈希数组数据结构
在顶层的for循环中:
*循环遍历结果数组
*打印列号
*获取该列中使用的值
*按出现的次数对值进行
排序*基于值的二级排序(例如b vs g vs m vs z)
*使用排序后的列表遍历结果哈希
*打印每次出现的值和编号
column 0:
a 3
z 3
t 1
v 1
w 1
column 1:
d 3
r 2
b 1
g 1
m 1
z 1
column 2:
c 4
a 3
e 2
Run Code Online (Sandbox Code Playgroud)
如果您的输入文件是.csv,请更改/\s+/
为/,/
在一个丑陋的比赛中,Perl装备精良。
这种单线执行相同的操作:
perl -lane 'for $i (0..$#F){$g[$i]{$F[$i]}++};END{for $j (0..$#g){print "$j:";for $k (sort{$g[$j]{$b}<=>$g[$j]{$a}||$a cmp $b} keys %{$g[$j]}){print " $k $g[$j]{$k}"}}}' files*
Run Code Online (Sandbox Code Playgroud)