添加中间列,跳过并保留一些行/列

时间:2015-04-22 12:39:38

标签: python perl csv

我是编程新手,但我已经开始研究Python和Perl。

我正在寻找两个部分为CSV的输入文件中的数据,选择其中一些并放入新的输出文件。

也许Python CSV或Pandas可以在这里提供帮助,但在跳过/保留行和列时我有点困惑。

另外,我的列没有任何标题。

输入文件1:

-- Some comments
KW1
'Z1' 'F' 30 26 'S'
KW2
'Z1' 30 26 1 1 5 7 /
'Z1' 30 26 2 2 6 8 /
'Z1' 29 27 4 4 12 13 /

输入文件2:

-- Some comments
-- Some more comments
KW1
'Z2' 'F' 40 45 'S'
KW2
'Z2' 40 45 1 1 10 10 /
'Z2' 41 45 2 2 14 15 /
'Z2' 41 46 4 4 16 17 /

所需的输出文件:

KW_NEW
'Z_NEW' 1000 30 26 1 /
'Z_NEW' 1000 30 26 2 /
'Z_NEW' 1000 29 27 4 /
'Z_NEW' 1000 40 45 1 /
'Z_NEW' 1000 41 45 2 /
'Z_NEW' 1000 41 46 4 /

所以我想做的是:

  • 在我到达KW2

  • 之前,请勿在我的两个输入文件中包含任何内容
  • KW2替换为KW_NEW

  • 在第一栏中替换Z1' or Z2 with Z_NEW`

  • 添加一个具有常量值的新第二列,例如1000

  • 复制接下来的三列

  • 在最后打印斜杠/之前,请先删除所有剩余的列

有人能给我至少一些一般提示/提示如何处理这个问题吗?

3 个答案:

答案 0 :(得分:1)

您的文件不是"部分是csv" (看不到逗号);它们(部分) space 分隔。您可以逐行阅读文件,使用Python的.split()方法将相关字符串转换为子字符串列表,然后根据需要重新排列。拆分和重新组装可能如下所示:

input_line = "'Z1' 30 26 1 1 5 7 /"  # test data
input_items = input_line.split()
output_items = ["'Z_NEW'", '1000']
output_items.append(input_items[1])
output_items.append(input_items[2])
output_items.append(input_items[3])
output_items.append('/')
output_line = ' '.join(output_items)
print(output_line)

最后的print()语句显示结果字符串是

'Z_NEW' 1000 30 26 1 /

答案 1 :(得分:0)

您的文件格式是否为静态? (顺便说一下,这实际上不是csv:P)您可能希望调查标准化的文件格式,如JSON或严格的CSV来存储数据,以便您可以使用已有的工具来解析输入文件。 python有很棒的JSON和CSV库,可以为你完成所有难题。

如果你坚持使用这种文件格式,我会尝试这些方法。

path = '<input_path>'
kws = ['KW1', 'KW2']
desired_kw = kws[1]

def parse_columns(line):
    array = line.split()
    if array[-1] is '/':
        # get rid of trailing slash
        array = array[:-1]

def is_kw(cols):
    if len(cols) > 0 and cols[0] in kws:
        return cols[0]

# to parse the section denoted by desired keyword
with open(path, 'r') as input_fp:
    matrix = []
    reading_file = False
    for line in input_fp.readlines:
        cols = parse_columns(line)
        line_is_kw = is_kw(line)
        if line_is_kw:
            if not reading_file:
                if line_is_kw is desired_kw:
                    reading_file = True
                else:
                    continue
            else:
                break

        if reading_file:
            matrix = cols

print matrix

从那里你可以使用切片表示法和基本列表操作之类的东西来获得你想要的数组。祝你好运!

答案 2 :(得分:-1)

以下是Perl的一种方法:

#!/usr/bin/perl
use strict;
use warnings;

# initialize output array
my @output = ('KW_NEW');

# proceed first file
open my $fh1, '<', 'in1.txt' or die "unable to open file1: $!";
while(<$fh1>) {
    # consider only lines after KW2
    if (/KW2/ .. eof) {
        # Don't treat KW2 line
        next if /KW2/;
        # split the current line on space and keep only the fifth first element
        my @l = (split ' ', $_)[0..4];
        # change the first element
        $l[0] = 'Z_NEW';
        # insert 1000 at second position
        splice @l,1,0,1000;
        # push into output array
        push @output, "@l";
    }
}

# proceed second file
open my $fh2, '<', 'in2.txt' or die "unable to open file2: $!";
while(<$fh2>) {
    if (/KW2/ .. eof) {
        next if /KW2/;
        my @l = (split ' ', $_)[0..4];
        $l[0] = 'Z_NEW';
        splice @l,1,0,1000;
        push @output, "@l";
    }
}

# write array to output file
open my $fh3, '>', 'out.txt' or die "unable to open file3: $!";
print $fh3 $_,"\n" for @output;