Linux 在unix中转置文件

Linux 在unix中转置文件,linux,unit-testing,unix,grep,Linux,Unit Testing,Unix,Grep,我有这样的文件 1111,K1 2222,L2 3333,LT50 4444,K2 1111,LT50 5555,IA 6666,NA 1111,NA 2222,LT10 需要的产出 1111,K1,LT50,NA 2222,L2,LT10 3333,LT50 4444,K2 5555,IA 6666,NA 第1列编号可能随时重复,但我需要的输出是sort和uniq,这里是一个可以理解的尝试,使用非标准工具SQLite shell。数据库在内存中 echo 'create table

我有这样的文件

1111,K1
2222,L2
3333,LT50
4444,K2
1111,LT50
5555,IA
6666,NA
1111,NA
2222,LT10
需要的产出

1111,K1,LT50,NA
2222,L2,LT10
3333,LT50
4444,K2
5555,IA
6666,NA

第1列编号可能随时重复,但我需要的输出是sort和uniq,这里是一个可以理解的尝试,使用非标准工具SQLite shell。数据库在内存中

echo    'create table tmp (a int, b text);
        .separator ,
        .import file.txt tmp
        .output out.txt
        SELECT a, group_concat(b) FROM tmp GROUP BY a ORDER BY a ASC;
        .output stdout
        .q' | sqlite

下面是使用非标准工具SQLite shell的一个可以理解的尝试。数据库在内存中

echo    'create table tmp (a int, b text);
        .separator ,
        .import file.txt tmp
        .output out.txt
        SELECT a, group_concat(b) FROM tmp GROUP BY a ORDER BY a ASC;
        .output stdout
        .q' | sqlite
如果你有一个大文件,你可以试着每隔几行打印一次

BEGIN{FS=","}
{ a[$1]=a[$1]FS$2 }
NR%50000==0 {
  for(i in a) { print  a[i] }
  delete a  #delete array so it won't take up memory
}
END{
  for(i in a){ print a[i] }
}
如果你有一个大文件,你可以试着每隔几行打印一次

BEGIN{FS=","}
{ a[$1]=a[$1]FS$2 }
NR%50000==0 {
  for(i in a) { print  a[i] }
  delete a  #delete array so it won't take up memory
}
END{
  for(i in a){ print a[i] }
}

这是python中的解决方案。脚本从stdin读取数据

#!/usr/bin/env python
import sys
d = {}
for line in sys.stdin.readlines():
  pair = line.strip().split(',')
  d[pair[0]] = d.get(pair[0], [])
  d[pair[0]].append(str(pair[1]))
for key in sorted(d):
  print "%s,%s" % (key, ','.join(d[key]))

这是python中的解决方案。脚本从stdin读取数据

#!/usr/bin/env python
import sys
d = {}
for line in sys.stdin.readlines():
  pair = line.strip().split(',')
  d[pair[0]] = d.get(pair[0], [])
  d[pair[0]].append(str(pair[1]))
for key in sorted(d):
  print "%s,%s" % (key, ','.join(d[key]))

下面是Perl中的一个,但它不会特别有效:

#!/usr/bin/perl -w
use strict;
my %lines;
while (<>) {
    chomp;
    my ($key, $value) = split /,/;
    $lines{$key} .= "," if $lines{$key};
    $lines{$key} .= $value;
}

my $key;
for $key in (keys(%lines)) {
    print "$key,$lines{$key}\n";
}
#/usr/bin/perl-w
严格使用;
我的%行;
而(){
咀嚼;
我的($key,$value)=拆分/,/;
$lines{$key}.=“,”如果$lines{$key};
$lines{$key}.=$value;
}
我的$key;
对于$key in(键(%lines)){
打印“$key,$lines{$key}\n”;
}
这样使用:

$ ./command <file >newfile
$。/命令新建文件
不过,使用多通道解决方案可能会更幸运。我真的没有时间给你写。这里有一个提纲:

  • 抓取并删除文件中的第一行
  • 解析文件的其余部分,连接任何匹配行并删除它
  • 在文件末尾,输出新的长行
  • 如果文件仍有内容,则循环回1

  • 下面是Perl中的一个,但它不会特别有效:

    #!/usr/bin/perl -w
    use strict;
    my %lines;
    while (<>) {
        chomp;
        my ($key, $value) = split /,/;
        $lines{$key} .= "," if $lines{$key};
        $lines{$key} .= $value;
    }
    
    my $key;
    for $key in (keys(%lines)) {
        print "$key,$lines{$key}\n";
    }
    
    #/usr/bin/perl-w
    严格使用;
    我的%行;
    而(){
    咀嚼;
    我的($key,$value)=拆分/,/;
    $lines{$key}.=“,”如果$lines{$key};
    $lines{$key}.=$value;
    }
    我的$key;
    对于$key in(键(%lines)){
    打印“$key,$lines{$key}\n”;
    }
    
    这样使用:

    $ ./command <file >newfile
    
    $。/命令新建文件
    
    不过,使用多通道解决方案可能会更幸运。我真的没有时间给你写。这里有一个提纲:

  • 抓取并删除文件中的第一行
  • 解析文件的其余部分,连接任何匹配行并删除它
  • 在文件末尾,输出新的长行
  • 如果文件仍有内容,则循环回1

  • 这与单元测试有什么关系?可以在一次过程中填充要列出的键的散列,然后在散列上迭代以获得所需的输出。您可能只想用支持散列和正则表达式的语言编写一个简单的脚本,例如Perl。这与单元测试有什么关系?可以在一次过程中填充要列出的键的散列,然后在散列上迭代以获得所需的输出。您可能只想用支持散列和正则表达式的语言编写一个简单的脚本,例如Perl.ghostdog74谢谢您的回复。。你的剧本写得很好。但我有一个问题,我有超过200万行的文件。。您使用的For循环可能需要很多时间。你对此有什么建议吗?200万排是多少?awk是一个非常快速的文本处理工具。我很怀疑它对你的问题会不会太慢。就像我说的,200万是多少?拉克斯是什么意思???把这些放在数字里。。。。20000行??2000000行??那么在您的系统上运行脚本需要多长时间?10分钟??30分钟??因为你有一个大文件,另一种方法是把你的文件分开,分别进行操作。然后在结束时,将结果合并。ghostdog74谢谢你的回复。。你的剧本写得很好。但我有一个问题,我有超过200万行的文件。。您使用的For循环可能需要很多时间。你对此有什么建议吗?200万排是多少?awk是一个非常快速的文本处理工具。我很怀疑它对你的问题会不会太慢。就像我说的,200万是多少?拉克斯是什么意思???把这些放在数字里。。。。20000行??2000000行??那么在您的系统上运行脚本需要多长时间?10分钟??30分钟??因为你有一个大文件,另一种方法是把你的文件分开,分别进行操作。最后,将结果合并。