从命令行对文本记录进行排序

时间:2014-03-15 05:09:49

标签: sorting vim command-line sed awk

我使用Linux并将我的联系人存储在文本文件中,格式如下,用5行星号分隔。我使用Vim打开并执行基本搜索。随着文件大小的增加,我想通过“标签”对联系人进行排序。或者'跟进日期'。我将记录看作是在索引卡上。这种格式可能或不适合我的目的,所以我愿意接受提示。

*****$
Name: Company A$
Email: companya@mail.com$
Phone: 555-555-5555$
Address:$
Business Type: Medical$
Notes:$
Follow Up Date: 12/05/2013$
Tag:  Tag6$
*****$
Name: Company B $
Email: companyb@mail.com$
Phone: 666-666-6666$
Address:$
Business Type: Food$
Notes:$
Follow Up Date: 12/03/2013$
Tag:  Tag7$
*****$

我理解Sed用于数据流,Awk用于delmited字段。我正在学习使用两者,但到目前为止我无法达到预期的效果。我也在学习使用Sort,基本上是从命令行处理我的文件。

有人可以协助我按照'标记排序记录。或者'跟进日期',在Vim中或从命令行向右?

谢谢大家

3 个答案:

答案 0 :(得分:1)

这可能不是一个完美的答案,但请尝试重新格式化信息。将地址卡中的所有信息保存在具有固定长度或制表符/逗号分隔字段的单个记录中。然后,您就可以在任何字段上对其进行排序。例如:

|Rec0001|Name1        |email1@email.com       |091-909090990 | ......|tag1   |tag2
|Rec0002|Name2        |email2@email2.com      |091-909090991 | ......|tagx   |tagy

答案 1 :(得分:1)

我终于明白OP需要按follow up date对记录(段落)进行排序,而不是对每一行进行排序。

以下是我根据OP的要求制作的示例源文件。

$ cat file
*****
Name: A
Email:
Phone:
Address:
Business Type:
Notes:
Follow Up Date: 12/03/2013 
Tag:  Tag1, Tag1, Tag3
*****
Name: B
Email:
Phone:
Address:
Business Type:
Notes:
Follow Up Date: 2/28/2014
Tag:  Tag1, Tag1, Tag3
*****

以下是使用follow up date对两个记录进行排序的命令:

awk '{gsub(/\n/,"|")}1' RS="*+\n"  file |sort -hr|awk '{gsub(/\|/,"\n");print "*****" RS $0}' 

*****
Name: B
Email:
Phone:
Address:
Business Type:
Notes:
Follow Up Date: 2/28/2014
Tag:  Tag1, Tag1, Tag3

*****
Name: A
Email:
Phone:
Address:
Business Type:
Notes:
Follow Up Date: 12/03/2013 
Tag:  Tag1, Tag1, Tag3

*****

解释

1)第一个awk命令会将每条记录转换为一行:

awk '{gsub(/\n/,"|")}1' RS="*+\n"  file

Name: A|Email:|Phone:|Address:|Business Type:|Notes:|Follow Up Date: 12/03/2013 |Tag:  Tag1, Tag1, Tag3|
Name: B|Email:|Phone:|Address:|Business Type:|Notes:|Follow Up Date: 2/28/2014|Tag:  Tag1, Tag1, Tag3|

2)sort -h排序比较人类可读数字的记录

3)第二个awk用于将记录转换回原始格式。

答案 2 :(得分:1)

我想出了一个类似于@ BMW的答案的vim方法。这两者并不完全相同:如果我正确地阅读@ BMW的解决方案,那么它将被其他领域的数字混淆; vim :sort的数字选项有限。 (如果您想按日期排序,如果您使用YYYYMMDD之类的格式,则没有标点符号会更简单。)

:v/\V*****/s/^/|
:g/\V*****/,/\V*****\|\%$/-j
:sort n /|Follow Up Date:/
:%s/|/\r/g

注意:

  1. 我使用不受欢迎的\V修饰符(非常无魔法),因此 * 不会被视为特殊字符。
  2. 无论您使用的是awk还是vim,您都可能想要使用比 | 更独特的东西。
  3. 如果文件末尾有一个空行,:g命令将正常工作。如果你不喜欢它,可以在此过程中添加和删除它。
  4. 使用:sort /|Tag:/按标签排序,而不是按照后续日期排序。