我想按出场次数对输入进行排序。但是我不想删除唯一或非唯一的行。例如,如果我得到以下输入:
Not unique
This line is unique
Not unique
Also not unique
Also unique
Also not unique
Not unique
我正在寻找一组输出以下内容的流水线命令:
This line is unique
Also unique
Also not unique
Also not unique
Not unique
Not unique
Not unique
感谢您提供的任何帮助,我一直在努力使用独特和排序的不同组合,但无法弄明白,解决方案最好是单线。
更新:感谢所有回复的人,尤其是@batMan,他的回答正是我用我熟悉的命令所寻找的。 p>
我还在尝试学习如何管理和使用多个命令来完成看似简单的任务,那么我是否可以调整他的答案来处理2列?例如,如果原始输入是:
Notunique dog
Thislineisunique cat
Notunique parrot
Alsonotunique monkey
Alsounique zebra
Alsonotunique beaver
Notunique dragon
我希望输出按第一列排序,如下所示:
Thislineisunique cat
Alsounique zebra
Alsonotunique monkey
Alsonotunique beaver
Notunique dog
Notunique parrot
Notunique dragon
感谢大家提前提供的帮助!
答案 0 :(得分:1)
仅 awk 最适合您的更新问题。
$ awk '{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;} END{ k=1; for(n=1; n<=max_count; n++){ for(i in count) if(count[i]==n) ordered[k++]=i} for(j in ordered) for( line in file) if (line~ordered[j]) print line; }' file
Alsounique zebra
Thislineisunique cat
Alsonotunique beaver
Alsonotunique monkey
Notunique parrot
Notunique dog
Notunique dragon
说明:
第1部分:
{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;}
:
我们将您的输入文件存储在file
数组中; count
数组会根据您希望对文件进行排序来跟踪每个唯一第一个字段的计数。 max_count
跟踪最大数量。
<强>部分-2:强>
awk完成读取文件后,count
的内容如下:(键,值)
Alsounique 1
Notunique 3
Thislineisunique 1
Alsonotunique 2
现在我们的目标是按值对这些键进行排序,如下所示。这是我们的关键步骤,对于下面输出中的每个字段/键/列1,我们将遍历file
数组并打印包含这些键的行,它将为我们提供最终所需的输出。
Alsounique
Thislineisunique
Alsonotunique
Notunique
下面的循环执行以count
方式将ordered
数组的内容存储在名为sorted by values
的另一个数组中的操作。 ordered
的内容与上面显示的输出相同。
for(n=1; n<=max_count; n++)
{
for(i in count)
if(count[i]==n)
ordered[k++]=i
}
最后一步:,即迭代file
数组并按照ordered
数组中存储的字段的顺序打印行。
for(field in ordered)
for( line in file)
if (line~ordered[field])
print line;
}
解决方案-2 :
另一种可能的解决方案是使用排序, uniq 和 awk / cut 。但是如果您的输入文件非常大,我不建议使用它,因为多个管道会调用多个进程,从而减慢整个操作的速度。
$ cut -d ' ' -f1 file | sort | uniq -c | sort -n | awk 'FNR==NR{ordered[i++]=$2; next} {file[$0]++;} END{for(j in ordered) for( line in file) if (line~ordered[j]) print line;} ' - file
Alsounique zebra
Thislineisunique cat
Alsonotunique beaver
Alsonotunique monkey
Notunique parrot
Notunique dog
Notunique dragon
以前的解决方案(在OP之前编辑问题)
可以使用sort
,uniq
和awk
完成此操作:
$ uniq -c <(sort f1) | sort -n | awk '{ for (i=1; i<$1; i++){print}}1'
1 Also unique
1 This line is unique
2 Also not unique
2 Also not unique
3 Not unique
3 Not unique
3 Not unique
答案 1 :(得分:0)
uniq
+ sort
+ grep
解决方案:
扩展inputfile
内容:
Not unique
This line is unique
Not unique
Also not unique
Also unique
Also not unique
Not unique
Also not unique
Also not unique
事先对初始文件进行排序:
sort inputfile > /tmp/sorted
uniq -u /tmp/sorted; uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8- \
| while read -r l; do grep -x "$l" /tmp/sorted; done
输出:
Also unique
This line is unique
Not unique
Not unique
Not unique
Also not unique
Also not unique
Also not unique
Also not unique
<强> ---------- 强>
您也可以将整个作业附加到bash
脚本中:
#!/bash/bash
sort "$1" > /tmp/sorted # $1 - the 1st argument (filename)
uniq -u /tmp/sorted
while read -r l; do
grep -x "$l" /tmp/sorted
done < <(uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8-)
答案 2 :(得分:0)
我会使用awk
来计算每行发生的次数,然后打印出来(按频率预先设定)并使用sort -n
进行数字排序:
awk 'FNR==NR{freq[$0]++; next} {print freq[$0],$0}' data.txt data.txt | sort -n
示例输出
1 Also unique
1 This line is unique
2 Also not unique
2 Also not unique
3 Not unique
3 Not unique
3 Not unique
这真是一个施瓦茨变换。如果要丢弃前导频率列,只需将| cut -d ' ' -f 2-
添加到命令的末尾。