更改csv文件中的列号

时间:2014-09-26 13:34:29

标签: python awk sed grep

我有一个带有3列

的管道分隔文件
aaa|xyz|pqr
another|column
with
line break | last column

预期输出为:

aaa|xyz|pqr
another|column with line break | last column

如果我删除换行符,那么我会得到一条这样的行...

aaa|xyz|pqr another|column with line break | last column

但我每行需要3列。

3 个答案:

答案 0 :(得分:2)

Python解决方案:

import sys

def fix_rows(it, n):
    row = ''
    for line in it:
        if row:
            row = row.rstrip('\n') + ' ' + line
        else:
            row = line
        if row.count('|') == n - 1:
            yield row
            row = ''
    if row:
        yield row

with open('a.csv') as f:
    sys.stdout.writelines(fix_rows(f, 3))

输出:

aaa|xyz|pqr
another|column with line break | last column

答案 1 :(得分:2)

您可以尝试此awk

awk -F'|' 'NF!=3{ line=line ? line " " $0 : $0; c=split( line, arr, "|"); if(c == 3){ $0=line; }else{ next } }1' yourfile

更具可读性awk版本:

#!/bin/awk -f

BEGIN{
          FS="|";
}

NF!=3{ 
          line=line ? line " " $0 : $0; 
          c=split( line, arr, "|"); 
          if(c == 3) {
                     $0=line; 
          }
          else { 
                     next;
          }
}1

<强>测试

$ awk -F'|' 'NF!=3{ line=line ? line " " $0 : $0; c=split( line, arr, "|"); if(c == 3){ $0=line; }else{ next } }1' yourfile
aaa|xyz|pqr
another|column with line break | last column

它适用于您的样本输入。

答案 2 :(得分:1)

您所描述的是遵循此模式的三场记录:

(F1, May have CR) | (F2, May have CR) | (F3, No CR)CR

如果F3确实有CR,那么哪个记录是不明确的,因为你不知道CR是终止记录还是嵌入到F3或后面的F1字段中。

您可以使用Perl中的正则表达式轻松解析我所描述的内容:

$ perl  -e '
$str = do { local $/; <> };
while ($str =~ /^\n?((?:[^|]+\|){2}[^\n]+)/gm){
    $_=$1;
    s/\n/ /g;
    print "$_\n";
}
' /tmp/ac.csv
aaa|xyz|pqr
another|column with line break | last column

通过使用正则表达式将记录与流分开来工作。

Live regex以显示其工作原理。