如何在 shell 中的每个组之后用换行符按名称对列表进行分组?

How to group a list by name with a newline after each group in shell?

我有一个要按名称分组的列表。这应该在每组之后用换行符来完成。 这是一个示例文件:

$ cat file
2015-07-09 07:03:46    7.5 GiB apple-foo.txt.gpg
2015-07-22 11:36:36    6.9 GiB apple-bar.txt.gpg
2015-07-27 04:40:34   31.0 GiB banana-here.txt.gpg
2015-07-07 20:28:17   30.6 GiB banana-even.txt.gpg
2015-07-19 15:02:20   30.8 GiB banana-more.txt.gpg
2015-07-26 00:05:11    1.9 GiB coconut-something.txt.gpg
2015-07-23 03:34:41    2.1 GiB coconut-else.txt.gpg
2015-07-24 03:34:40   12.1 GiB date-yougetit.txt.gpg

这是我想要得到的输出:

2015-07-09 07:03:46    7.5 GiB apple-foo.txt.gpg
2015-07-22 11:36:36    6.9 GiB apple-bar.txt.gpg

2015-07-27 04:40:34   31.0 GiB banana-here.txt.gpg
2015-07-07 20:28:17   30.6 GiB banana-even.txt.gpg
2015-07-19 15:02:20   30.8 GiB banana-more.txt.gpg

2015-07-26 00:05:11    1.9 GiB coconut-something.txt.gpg
2015-07-23 03:34:41    2.1 GiB coconut-else.txt.gpg

2015-07-24 03:34:40   12.1 GiB date-yougetit.txt.gpg

我设法提取了唯一名称(apple、banana、coconut、date),但我未能在每个唯一名称的最后一次出现后添加新行。 有人能帮我吗? awk 和 sed 是最受欢迎的。

一个awk解决方案:

awk -F\- 'NR>1&&!=last{print ""}{last=}1' infile

解释

-F\- :设置字段分隔符为.

NR>1 :省略检查的第一行。

last= :总是保存最后一次出现的组键.

1 :打印当前行。

1!=last{print ""} :如果 key </code> 是 <strong>NOT</strong> 等于 <code>last 打印分隔符.

更新

当前源使用:

awk 'split($NF,a,"-"){current=a[1]}NR>1&&current!=last{print ""}{last=current}1' infile

解释2

split($NF,a,"-"){current=a[1] :通过在 - 字符处拆分 $NF 行的最后一个字段来获取键 a[1]