2

我有一个如下所示的数据文件:

 xyz123            2.000    -0.3974     0.0  hij123       
                                          6.0  lmn123      
                                          8.7  efg123      
                                         13.9  uvw123      
                                         28.5  rst123       
 abc123            10.000     0.1943     0.0  wxy123       
                                         10.7  xyz123       
                                         19.9  pqr123     
                                         20.6  stu123      
                                         20.6  klm123      
 def123            50.000    -0.2595    19.2  jkl123      
                                         26.1  stu123      
                                         27.1  def123     
                                         27.1  ghi123     
                                         27.6  abc123

* uvw123 15.000 -0.3635

 lmn123            40.000    -0.3695     19.2  jkl123      
                                         26.1  stu123      
                                         27.1  def123     
                                         27.1  ghi123     
                                         27.6  abc123

我需要将其转换为:

xyz123,2.000,-0.3974,0.0,hij123       
xyz123,2.000,-0.3974,6.0,lmn123      
xyz123,2.000,-0.3974,8.7,efg123      
xyz123,2.000,-0.3974,13.9,uvw123      
xyz123,2.000,-0.3974,28.5,rst123       
abc123,10.000,0.1943,0.0,wxy123       
abc123,10.000,0.1943,10.7,xyz123       
abc123,10.000,0.1943,19.9,pqr123     
abc123,10.000,0.1943,20.6,stu123      
abc123,10.000,0.1943,20.6,klm123      
def123,50.000,-0.2595,19.2,jkl123      
def123,50.000,-0.2595,26.1,stu123      
def123,50.000,-0.2595,27.1,def123     
def123,50.000,-0.2595,27.1,ghi123     
def123,50.000,-0.2595,27.6,abc123

* uvw123,15.000,-0.3635,

lmn123,40.000,-0.3695,19.2,jkl123      
lmn123,40.000,-0.3695,26.1,stu123      
lmn123,40.000,-0.3695,27.1,def123     
lmn123,40.000,-0.3695,27.1,ghi123     
lmn123,40.000,-0.3695,27.6,abc123

如何使用 Python 或 AWK 或 sed 做到这一点?

更新:因此,如果您注意到输入数据中有一行看起来像“ uvw123 15.000 -0.3635 ”,并且当我使用来自 aix 的 python 代码时,该行会变得混乱。有没有办法修改您的代码并正确输出我展示的行?

4

8 回答 8

1

这是一个 Python 解决方案:

import re

with open('data.txt') as f:
  prev = []
  for line in f:
    tok = [t for t in re.split(r'\s+', line.rstrip()) if t]
    if len(tok) < len(prev):
      tok = prev[:-len(tok)] + tok
    print ','.join(tok)
    prev = tok

它跟踪每列 (in prev) 的最新值,并使用它来填充当前行中缺失的列。

于 2012-05-23T15:16:05.193 回答
1
awk 'BEGIN {OFS = ","} NF == 5 {a = $1; b = $2; c = $3; $1 = $1; print; next} {$4 = $1; $5 = $2; $1 = a; $2 = b; $3 = c; print}' inputfile

分成多行:

awk 'BEGIN {
        OFS = ","
    } 
    NF == 5 {
        a = $1; 
        b = $2; 
        c = $3; 
        $1 = $1; 
        print; 
        next
    } 
    {
        $4 = $1; 
        $5 = $2; 
        $1 = a; 
        $2 = b; 
        $3 = c; 
        print
    }' inputfile

这样做会$1 = $1迫使生产线与新的OFS.

于 2012-05-24T02:41:58.353 回答
0

使用 awk:

awk 'BEGIN{OFS="\t";} NF==2{print a,b,c,$1,$2}{};NF==5{a=$1; b=$2; c=$3;print $1,$2,$3,$4,$5}{}' logfile 

这首先将输出字段分隔符设置为选项卡(您可以根据需要进行更改),然后查看行中有多少列。如果有 5 个,它将前三个设置为变量 a、b 和 c,然后将它们全部打印出来。

如果只有两列,则打印 a、b 和 c(即最后一整行的前三列),然后是该行的两列。

更新:

我没有注意到只有三列的行!下面的 awk 命令应该提供您指定的输出:

awk 'BEGIN{OFS="\t";} $1~/^[a-z]/{a=$1; b=$2; c=$3;print $1,$2,$3,$4,$5}{}$1!~/^[a-z]/{print a,b,c,$1,$2}{}' logfile

这与以前类似,但查看第一个字段是否以字母开头,而不是查看列数。如果需要,这个正则表达式可以更具体。

于 2012-06-14T16:13:17.850 回答
0

假设文件是​​制表符分隔的。

您可以迭代每一行,并应用于split("\t")每一行,例如

for line in lines:
    result = line.split("\t")

如果 len(result) 是 5,那么你点击了一个新的部分。您可以像这样解压缩这些值

h1, h2, h3, v1, v2 = result

否则,它是

v1, v2 = result

然后,您可以使用 打印出变量",".join([h1, h2, h3, v1, v2])

至于第二个问题,没有看到文件中的隐形字符,很难分辨。例如,您可以通过在 vi 中使用“设置列表”来查看它们。

于 2012-06-14T15:58:52.163 回答
0

一个awk(和tr)解决方案,不是特别优雅:

awk 'BEGIN { OFS = ","}
  { if (NF == 5) {
    split($0, a); print $1, $2, $3, $4, $5
  } else {
    print a[1], a[2], a[3], $1, $2
  } }' | tr -d ' \t'
于 2012-05-23T16:36:57.253 回答
0

使用 awk:

awk 'BEGIN {OFS=","} /^[^ ]/ {f1=$1; f2=$2; f3=$3; f4=$4; f5=$5} /^[ ]/ {f4=$1; f5=$2}  {print f1,f2,f3,f4,f5}' < input.txt
于 2012-06-14T16:09:10.953 回答
0

你可以尝试这样的事情开始 -

awk 'NF>3{a=$1;b=$2;c=$3;$1=$1;print;next}NF<3{d=$1;e=$2;print a,b,c,d,e;next}{$1=$1;}1' OFS=',' file
于 2012-06-14T16:52:09.077 回答
-1

一个简单的 grep 就可以做到

$ cat so.txt 
xyz123 2.000 -0.3974 0.0 hij123
6.0 lmn123
8.7 efg123
13.9 uvw123
28.5 rst123
abc123 10.000 0.1943 0.0 wxy123
10.7 xyz123
19.9 pqr123
20.6 stu123
20.6 klm123
def123 50.000 -0.2595 19.2 jkl123
26.1 stu123
27.1 def123
27.1 ghi123
27.6 abc123
$ cat so.txt | grep "-"
xyz123 2.000 -0.3974 0.0 hij123
def123 50.000 -0.2595 19.2 jkl123
于 2012-05-23T15:17:32.453 回答