我需要对 shell 脚本中作为参数给出的文件中的所有单词进行排序。下面是一行代码:
tr [:space:] '\n' <$1 | sort -nrk2,2 | uniq -c |sed 's/^ \+//g'
基本上,如果我的文件中存在类似这样的内容:
bla bla bla bla hu hu hu
它将输出
4 bla
3 hu
我希望它们像
bla 4
hu 3
答案1
你可以sed
用一个简单的awk
命令来替换你的命令,该命令可以交换字段顺序
... | awk '{print $2,$1}'
答案2
有很多方法可以做到这一点。Steeldriver 已经为您提供了经典awk
方法。以下是其他一些选择:
用于
sed
捕获两组非空白(\S
)字符,然后交换它们:... | sed -E 's/\s*(\S+)\s+(\S+)/\2 \1/'
使用
perl
。其-a
开关使其工作方式类似于awk
。它将自动在空格上拆分每个输入行,并将每个字段保存为数组的一个元素@F
。因此,第一个字段将是$F[0]
,第二个字段将是$F[1]
,依此类推:... | perl -lane 'print "$F[1] $F[0]"'
全部使用 Perl 来完成:
perl -lane '$k{$_}++ for @F; }{ print "$_ $k{$_}" for keys(%k)' "$1"
这里,
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"
第一个
for
循环遍历每个字段,并将数组中与该字段关联的值加一a
。然后,在文件末尾,它循环遍历每个元素a
并打印元素(单词)和关联值(该单词出现的次数)。将 shell 与原始管道一起使用:
... | while read a b; do echo "$b $a"; done