更改csv fi中的列号

2024-04-25 14:06:29 发布

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

我有一个以管道分隔的文件,有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列。你知道吗


Tags: 文件管道withlineanothercolumnlastbreak
3条回答

您描述的是一个三字段记录,遵循以下模式:

(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来说明它是如何工作的。你知道吗

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

你可以试试这个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

它正在为您的示例输入工作。你知道吗

相关问题 更多 >