我必须对在 shell 脚本中作为参数给出的文件中的所有单词进行排序。这是单线:
tr [:space:] '\n' <$1 | sort -nrk2,2 | uniq -c |sed 's/^ \+//g'
Run Code Online (Sandbox Code Playgroud)
基本上,如果我的文件中有这样的内容:
bla bla bla bla hu hu hu
Run Code Online (Sandbox Code Playgroud)
它会输出
4 bla
3 hu
Run Code Online (Sandbox Code Playgroud)
我希望他们像
bla 4
hu 3
Run Code Online (Sandbox Code Playgroud)
有很多很多方法可以做到这一点。Steeldriver 已经为您提供了经典awk方法。以下是一些其他选择:
使用sed以捕获两组非空白的(\S)字符,然后切换他们身边:
... | sed -E 's/\s*(\S+)\s+(\S+)/\2 \1/'
Run Code Online (Sandbox Code Playgroud)使用perl. 它的-a开关使它像awk. 它将自动在空白处拆分每个输入行并将每个字段保存为数组的一个元素@F。因此,第一个字段将是$F[0],第二个$F[1]等:
... | perl -lane 'print "$F[1] $F[0]"'
Run Code Online (Sandbox Code Playgroud)全部使用 Perl:
perl -lane '$k{$_}++ for @F; }{ print "$_ $k{$_}" for keys(%k)' "$1"
Run Code Online (Sandbox Code Playgroud)
在这里,perl逐行读取输入文件并将脚本应用于每一行。$k{$_}++ for @F将每个单词(来自 的每个字段@F)保存为散列中的一个键,%k并且每次看到该单词时将关联的值加一。然后,在文件被处理后(这就是}{意思),它会打印单词 ( $_) 以及$k{$_}存储在散列中的每个键的出现次数 ( )。
使用awk整个事情:
awk '{for(i=1;i<=NF;i++){a[$i]++}}END{for(i in a){print i,a[i]}}' "$1"
Run Code Online (Sandbox Code Playgroud)
第一个for循环遍历每个字段,并将一个与数组中与该字段关联的值相加a。然后,在文件末尾,它循环遍历每个元素a并打印元素(单词)和相关值(单词出现的次数)。
将 shell 与原始管道一起使用:
... | while read a b; do echo "$b $a"; done
Run Code Online (Sandbox Code Playgroud)