转换文件格式

2024-09-29 23:15:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下示例文件(a),我想使用Unix或Python命令将其转换为示例文件(b)。我的实际文件要大得多(几GB)。你知道吗

(一):

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

有人能帮忙吗?你知道吗


Tags: 文件命令示例unixnaclgbsolh2o2
3条回答

如果源数据是ch_源.txt,此脚本将创建_dst.txt文件以上面的格式。但在这个过程中会占用大量内存,因为在创建输出文件之前,必须存储所有数据。你知道吗

这是一个python2脚本。为了节省空间,python3脚本必须使用字节,并且将使用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')

我将提供3种解决方案—Awk、Perl和python2。你知道吗

Awk

这是一个运行awk的shell脚本:

#!/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] }' "$@"

Perl

#!/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}});
}

Python2

#!/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相同的不区分大小写的排序输出是可行的。你知道吗

基本上,你需要读取文件中的每一行,把每一行拆分成它的组成词,然后为每个分子记录它在什么溶液中出现。在python中,存储这些信息的最自然的数据结构是dict,键是分子,值是包含分子的解决方案列表。一旦构建了dict,就只需将每个条目写入一个文件。你知道吗

这应该足够让你开始了。试一试,如果你不能让它发挥作用,就带着具体的问题回来。你知道吗

相关问题 更多 >

    热门问题