我有一个丑陋的数据文件需要清理 -
Date User Name Item Id Title Quantity Price Total Amount
1/1/2015 name1 461064485 Description One Has Spaces 1 $899.99 $899.99
Real Name 1 Real Address With Spaces Location, Real 55555 555-555-5555
1/2/2015 name2 has spaces 461222501 Description still has spaces 1 $229.99 $229.99
Real Name Real Address 2 w spaces Real Location2 55556 555-555-5556
到目前为止效果最好:
awk -F " +" '/^[0-9]\/*[0-9]\// {print $1, $3, $5, $6, $7}' Table.txt > x.txt
但挂断了用户名太长并且与项目 ID 只相差一个空格。在这种情况下,$2 就变成了所需的 $2+$3。
我尝试过条件分割和打印
awk -F " +" '/^[0-9]*\/*[0-9]\// {if ( length ($2) >= 15 ) brokenfield=$2 split(brokenfield,subfields," "); print $1, subfields[-1], $4, $5, $6} {if (length ($2) < 15) print $1, $3, $5, $6, $7}' Table.txt > x.txt
它可以工作,但会处理所有内容,或者处理两次;或者
awk -F " +" '/^[0-9]\/*[0-9]\// {if ( length ($2) >= 15 ) brokenfield=$2 split(brokenfield,subfields," ") print "$1, subfields[-1], $4, $5, $6"; else print "$1, $3, $5, $6, $7" }' Table.txt > x.txt
但如果不处理该行两次,处理所有行(不知道为什么,因为搜索算法应该只处理以日期开头的行),或者出现有关打印或我的 else 语句的错误,我就无法获得正确的语法。
我计划升级到 printf,这样我也有固定的列宽,但我无法使我的语法正确。
所需输出(最好是固定列宽):
1/1/2015 461064485 1 $899.99 $899.99
1/2/2015 461222501 1 $229.99 $229.99
答案1
我采用了你的一个版本并做了一些修改:
awk -F " +" -v'OFS=\t' '/^[0-9]+\/[0-9]+\//{ \
if(length($2)>=15){ \
brokenfield=$2; n=split(brokenfield,subfields," "); \
print $1,subfields[n],$4,$5,$6 \
} \
else {print $1,$3,$5,$6,$7} \
}' file
输出:
1/1/2015 461064485 1 $899.99 $899.99
1/2/2015 461222501 1 $229.99 $229.99
几点说明:
{}
你忘了在条件语句两边加上大括号- 我不认为
awk
支持负数组索引(至少不支持我的gawk
) split
返回数组元素的数量,因此您可以将其用作最后一个数组元素的索引(n
在上面的情况下)\t
用作输出字段分隔符以便很好地对齐列