Linux 从一个巨大的(有数百万条记录和列)OFS文件(没有固定的头行)unix中查找所有唯一的列

Linux 从一个巨大的(有数百万条记录和列)OFS文件(没有固定的头行)unix中查找所有唯一的列,linux,unix,awk,sed,Linux,Unix,Awk,Sed,输入 k1可以是带有字母数字和的任何名称:特殊字符,如abc.nm.1:1 预期输出(所有唯一列),不需要排序/不需要排序,应该非常快 119764469|14100733//1,k1=v1,k2=v2,STREET:1:1=NY 119764469|14100733//1,k1=v1,k2=v2,k3=v3 119764469|14100733//1,k1=v1,k4=v4,abc.xyz:1:1=nmb,abc,po.foo:1:1=yu 我目前的方法/解决方案是 k1,k2,STREE

输入

k1可以是带有字母数字和的任何名称:特殊字符,如abc.nm.1:1

预期输出(所有唯一列),不需要排序/不需要排序,应该非常快

119764469|14100733//1,k1=v1,k2=v2,STREET:1:1=NY
119764469|14100733//1,k1=v1,k2=v2,k3=v3 
119764469|14100733//1,k1=v1,k4=v4,abc.xyz:1:1=nmb,abc,po.foo:1:1=yu
我目前的方法/解决方案是

k1,k2,STREET:1:1,k3,k4,abc.xyz:1:1

awk-F',''{for(i=0;i使用
grep-o
仅grep您需要的部分:

awk -F',' '{for (i=0; i<=NR; i++) {for(j=1; j<=NF; j++){split($j,a,"="); print a[1];}}}' file.txt | awk '!x[$1]++' | grep -v '|' | sed -e :a -e '$!N; s/\n/ | /; ta'

sort
在此处是必需的,因为否则
uniq
不起作用)

使用
grep-o
仅对您需要的部分进行grep:

awk -F',' '{for (i=0; i<=NR; i++) {for(j=1; j<=NF; j++){split($j,a,"="); print a[1];}}}' file.txt | awk '!x[$1]++' | grep -v '|' | sed -e :a -e '$!N; s/\n/ | /; ta'

sort
在这里是必需的,因为否则
uniq
不起作用)

不确定速度,但试试看

grep -o -e '[^=,]\+=[^,]\+' file.txt |awk -F'=' '{print $1}' |sort |uniq |tr '\n' ',' |sed 's/,$/\n/'
>>> abc.xyz:1:1,k1,k2,k3,k4,STREET:1:1

我希望它比grep快,因为不涉及正则表达式。

不确定速度,但试试看

grep -o -e '[^=,]\+=[^,]\+' file.txt |awk -F'=' '{print $1}' |sort |uniq |tr '\n' ',' |sed 's/,$/\n/'
>>> abc.xyz:1:1,k1,k2,k3,k4,STREET:1:1

我希望它比grep快,因为不涉及正则表达式。

如果您真的不需要一行输出:

$ cut -d, -f2- file |        # select the key/value pairs
  tr ',' '\n'       |        # split each k=v to its own line
  cut -d= -f1       |        # select only keys
  sort -u           |        # filter uniques
  paste -sd,                 # serialize back to single csv line

abc.xyz:1:1,k1,k2,k3,k4,STREET:1:1

$awk-F'[,=]'{for(i=2;i如果您真的不需要一行输出:

$ cut -d, -f2- file |        # select the key/value pairs
  tr ',' '\n'       |        # split each k=v to its own line
  cut -d= -f1       |        # select only keys
  sort -u           |        # filter uniques
  paste -sd,                 # serialize back to single csv line

abc.xyz:1:1,k1,k2,k3,k4,STREET:1:1

$awk-F'[,=]''{for(i=2;不需要isorting,列名可以是任何可能具有的名称。&:作为特殊字符,OPupdated@BaajiRao根据新要求编辑不需要,列名可以是任何可能具有的内容。&:作为特殊字符,OPupdated@BaajiRao根据新要求编辑我认为你可以去掉外部的颂歌>为(i=0;iIf性能是一个问题,因为您处理的是大文件,您可以编写一个很小的C程序并在目标机器上进行编译。@BasileStryneVitch C程序对于此类任务通常不会比awk脚本快,因为awk针对此特定任务进行了高度优化,而人们通常使用C编写代码来完成此任务不是。我想你可以把外面的
去掉(i=0;iIf性能是一个问题,因为您处理的是大文件,您可以编写一个很小的C程序并在目标机器上进行编译。@BasileStryneVitch C程序对于此类任务通常不会比awk脚本快,因为awk针对此特定任务进行了高度优化,而人们通常使用C编写代码来完成此任务是不是。根据要求效果很好,我刚刚更新了一点输入数据。我不希望“abc”作为我的列,所以我在tr之后使用了“grep\:”作为我期望的列(键)我只是想知道是否还有其他替代品可以替代这个“grep\”?还有,如果我需要“|”作为delim而不是像abc那样的“,”怎么办。xyz:1:1 | k1 | k2 | k3 | k4 | STREET:1:1按照要求工作得很好,我刚刚更新了一点输入数据。我不想让“abc”作为我的专栏,所以我在tr之后使用了“grep\”,正如我所期望的那样ed列(键)会有“:”字符,我只是想知道是否还有其他选项可以替代这个“grep\:”?另外,如果我需要“|”作为delim而不是像abc.xyz:1:1 | k1 | k3 | k4 | STREET:1:1