我有以下示例文件(a),我想使用Unix或Python命令将其转换为示例文件(b)。我的实际文件要大得多(几GB)。
(A):
Sol_00000001 H2O2 KNMO4 NaCl
Sol_00000002 NaCl NaCl
Sol_00000003 KOCl NHO2 NHO2
Sol_00000004 H2O2
Sol_00000005 KNMO4
Sol_00000006 NaCl
Sol_00000007 KOCl
Sol_00000008 NHO2
Sol_00000009 H2O2 NaCl KOCl NHO2 KNMO4
(B):
NaCl Sol_00000001 Sol_00000002 Sol_00000006 Sol_00000009
KOCl Sol_00000003 Sol_00000007 Sol_00000009
H2O2 Sol_00000001 Sol_00000004 Sol_00000009
NHO2 Sol_00000003 Sol_00000008 Sol_00000009
KNMO4 Sol_00000001 Sol_00000005 Sol_00000009
有人可以帮忙吗?
答案 0 :(得分:2)
我将提供3种解决方案 - 在Awk,Perl和Python 2中。
这是一个运行awk
:
#!/bin/sh
awk '{ for (i = 2; i <= NF; i++) list[$i] = list[$i] " " $1 }
END { for (i in list) printf "%-7s %s\n", i, list[i] }' "$@"
#!/usr/bin/env perl
use strict;
use warnings;
my %list = ();
while (<>)
{
my ($chem, @soln) = split;
push @{$list{$_}}, $chem foreach (@soln);
}
for my $key (sort { lc($a) cmp lc($b) } keys %list)
{
printf "%-7s %s\n", $key, join(' ', @{$list{$key}});
}
#!/usr/bin/env python
import fileinput
list = {}
for line in fileinput.input():
bits = line.split()
for i in range(1, len(bits)):
if bits[i] not in list:
list[bits[i]] = []
list[bits[i]].append(bits[0])
for key in sorted(list.keys(), key = str.lower):
print "%-7s %s" % (key, ' '.join(list[key]))
$ sh so.32062773.sh so.32062773.data
NaCl Sol_00000001 Sol_00000002 Sol_00000002 Sol_00000006 Sol_00000009
H2O2 Sol_00000001 Sol_00000004 Sol_00000009
KNMO4 Sol_00000001 Sol_00000005 Sol_00000009
KOCl Sol_00000003 Sol_00000007 Sol_00000009
NHO2 Sol_00000003 Sol_00000003 Sol_00000008 Sol_00000009
$ perl so.32062773.pl so.32062773.data
H2O2 Sol_00000001 Sol_00000004 Sol_00000009
KNMO4 Sol_00000001 Sol_00000005 Sol_00000009
KOCl Sol_00000003 Sol_00000007 Sol_00000009
NaCl Sol_00000001 Sol_00000002 Sol_00000002 Sol_00000006 Sol_00000009
NHO2 Sol_00000003 Sol_00000003 Sol_00000008 Sol_00000009
$ python so.32062773.py so.32062773.data
H2O2 Sol_00000001 Sol_00000004 Sol_00000009
KNMO4 Sol_00000001 Sol_00000005 Sol_00000009
KOCl Sol_00000003 Sol_00000007 Sol_00000009
NaCl Sol_00000001 Sol_00000002 Sol_00000002 Sol_00000006 Sol_00000009
NHO2 Sol_00000003 Sol_00000003 Sol_00000008 Sol_00000009
$
awk
不会尝试对键进行排序。将输出传递给sort -f
以获得与Perl和Python相同的不区分大小写的排序输出是可行的。
答案 1 :(得分:1)
如果您的源数据位于ch_source.txt中,则此脚本将以上述格式创建ch_dst.txt。但它会在进程中使用大量内存,因为在创建输出文件之前必须存储所有数据。
这是一个Python 2脚本。 Python 3脚本必须使用字节才能节省空间,并且使用items
代替iteritems
。
通过更多研究,您将了解如何在命令行上传递文件名,而不是将其硬编码到脚本中。
#! /usr/bin/env python2
import collections
def translate(srcf, dstf):
by_chem = collections.defaultdict(list)
with open(srcf, 'rb') as f:
for line in f:
values = line.split()
if not values:
continue
soln = values.pop(0)
for chem in values:
by_chem[chem].append(soln)
with open(dstf, 'wb') as f:
for chem, solns in sorted(by_chem.iteritems()):
f.write('%s\t%s\n' % (chem, '\t'.join(solns)))
translate('ch_source.txt', 'ch_dst.txt')
答案 2 :(得分:0)
基本上,您需要读取文件的每一行,将该行拆分为其组成单词,然后为每个分子记录它发生的解决方案。在python中,用于存储此信息的最自然的数据结构是一个字典。键是分子,值是含有分子的溶液列表。一旦构建了dict,就必须将每个条目写入文件。
这应该足以让你入门。小心一点,如果你无法解决问题,请回过头来回答。