Text linux中基于名称的文本文件分组

Text linux中基于名称的文本文件分组,text,awk,terminal,Text,Awk,Terminal,使用linux时,没有在regex或awk方面的丰富经验,也不知道最好的方法是什么 我有一个文本文件,看起来像 492 "Steve Smith" 455 "Steve Smith" 322 "Steve Smith" 123 "John Doe" 234 "John Doe" etc. 我期望的输出是: Steve Smith - 492, 455, 322 John Doe - 123, 234 下面的awk可能会在同样的情况下帮助您 解决方案一: 输出如下 "John Doe" - 1

使用linux时,没有在regex或awk方面的丰富经验,也不知道最好的方法是什么

我有一个文本文件,看起来像

492 "Steve Smith"
455 "Steve Smith"
322 "Steve Smith"
123 "John Doe"
234 "John Doe"
etc.
我期望的输出是:

Steve Smith - 492, 455, 322
John Doe - 123, 234

下面的
awk
可能会在同样的情况下帮助您

解决方案一:

输出如下

"John Doe" - 123, 234
"Steve Smith" - 492, 455, 322
"Steve Smith" - 492, 455, 322
"John Doe" - 123, 234
解决方案2:如果您希望按照输入文件以相同的顺序输出,那么以下内容也可以帮助您实现相同的顺序

awk '{
match($0,/".*"/);
val=substr($0,RSTART,RLENGTH);
}
!b[val]++{
  num++
}
{
a[val]=a[val]?a[val] OFS $1:$1;
c[num]=a[val];
d[num]=val
}
END{
for(i=1;i<=num;i++){
  print d[i]" - "c[i]
}}
' OFS=", "   Input_file
第一个解决方案的说明:

这会得到您想要的(但不带逗号):

要包含逗号,请执行以下操作:

$ awk -F'"' '{a[$2]=a[$2]$1} END{for (name in a) printf "%s - %s\n",name,a[name]}' file
Steve Smith - 492 455 322 
John Doe - 123 234 
$ awk -F'"' '{a[$2]=a[$2]", "$1+0} END{for (name in a) printf "%s - %s\n",name,substr(a[name],3)}' file
Steve Smith - 492, 455, 322
John Doe - 123, 234
工作原理
  • -F'

    这告诉awk使用双引号,
    ”作为字段分隔符。这样,数字是字段1,名称是字段2

  • a[$2]=a[$2],“$1+0

    对于每一行,我们使用键
    $2
    将逗号和数字附加到关联数组
    a
    的值

    第二个字段是名称,
    $2
    a[$2]
    是该名称的数字列表。对于我们阅读的每一行,我们都将
    a[$2]
    替换为先前的
    a[$2]
    ,后跟逗号空格,后跟第一个字段加零,
    $1+0
    。我们使用
    +0
    强制第一个字段为数字。这消除了第一个字段中的额外空间

  • END{for(a中的名称)printf“%s-%s\n”,name,substr(a[name],3)}

    到达文件末尾后,我们打印每个名称,后跟一个空格破折号,后跟数字列表。
    substr
    函数从数字字符串的开头删除多余的逗号

    姓名按任意顺序打印。您可能希望通过
    sort
    传递输出以按字母顺序排列


您可以将文件导入sqlite3数据库,并进行select查询

$ sudo apt install sqlite3
$ sqlite3
> create table test (num integer, name  text);
> .separator " "
> .import your_file test
> select name || " - " || group_concat(num) from test group by name;

如果您使用,您甚至不需要执行这些步骤,只需从test.txt group by c2中选择c2 | | |-| | group|u concat(c1)这是一个我没有想到的非常有趣的解决方案,谢谢!非常感谢每一部分的分解
$ awk -F'"' '{a[$2]=a[$2]", "$1+0} END{for (name in a) printf "%s - %s\n",name,substr(a[name],3)}' file
Steve Smith - 492, 455, 322
John Doe - 123, 234
$ sudo apt install sqlite3
$ sqlite3
> create table test (num integer, name  text);
> .separator " "
> .import your_file test
> select name || " - " || group_concat(num) from test group by name;