免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: sea_soft
打印 上一主题 下一主题

文本处理,比较难,谢谢 [复制链接]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
21 [报告]
发表于 2009-04-20 22:42 |只看该作者
awk -F, '{sub(".*|","",$1); $1=sprintf("%-9s", $1);
$2=sprintf("%-12s", $2);
$3=sprintf("%-7s", $3);
$4=sprintf("%-8s", $4);
$5=sprintf("%-15s", $5);
if (NF > 6) {for ( x = 7; x <= NF; x++ ) {$6=$6","$x}}; $6=sprintf("%-300s", $6);
print $1$2$3$4$5$6}'  test.dat

[ 本帖最后由 beginner-bj 于 2009-4-20 23:12 编辑 ]

论坛徽章:
0
22 [报告]
发表于 2009-04-20 23:45 |只看该作者
主要特点:
1、第7列数据中的逗号及|不处理
2、可以输出异常数据,如示例用555的这一行合法数据,666的这一行少一个数据列,为异常数据,仅输出到异常数据中
3、可以调试
4、如果对异常数据也想正常输出,改为r=match($0,"(^[^\\|]*)\\|?([^,]*),?([^,]*),?([^,]*),?([^,]*),?([^,]*),?(.*)$",a);即可
限制:
标准awk可能不支持带数组参数的match函数,如果没有gawk,试试nawk

echo "3453343|32444,asd,42,345sa,asda5445,asdsa|,asdaas,,asd,,,asdadsad||sadad,sad~@%asdasd32432|
232|as2d,421,3452sa,asda2544,asd121sa,erasdaaaas,asdasdadsadsadad,sad~|@%asdasdasdsda|
ab2|aspp2d,ass,23,aaa,bbb,ddsdd,asdasdadsadsadad,sad~|@%asdasd
333|555|bbb,ccc,ddd
555|a2,a3,a4,a5,a6,
666|a2,a3,a4,a5,a6
"|gawk '
{
  r=match($0,"(^[^\\|]*)\\|([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),(.*)$",a);
  #r=match($0,"(^[^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),(.*)$",a); #如果第1列也用,分隔,注解上一句,改用这一句.
  #printf("(%d,%s;%s,%s,%s,%s,%s,%s,%s):%s\n",r,RLENGTH,a[1,"length"],a[2,"length"],a[3,"length"],a[4,"length"],a[5,"length"],a[6,"length"],a[7,"length"],$0);#本句调试用,可加#注解掉
  if (r>0){
     printf("%-9s,%-12s,%-7s,%-8s,%-15s,%-300s\n",a[2],a[3],a[4],a[5],a[6],a[7]);
  } else if($0!=""){
     #printf("%d行数据异常(%s,%s,%s,%s,%s,%s,%s):%s\n",NR,a[1,"length"],a[2,"length"],a[3,"length"],a[4,"length"],a[5,"length"],a[6,"length"],a[7,"length"],$0) >>"error.log";#输出异常数据,如果不需要可加#注解掉
  }
}'
输出结果:
32444    ,asd         ,42     ,345sa   ,asda5445       ,asdsa|,asdaas,,asd,,,asdadsad||sadad,sad~@%asdasd32432|

as2d     ,421         ,3452sa ,asda2544,asd121sa       ,erasdaaaas,asdasdadsadsadad,sad~|@%asdasdasdsda|

aspp2d   ,ass         ,23     ,aaa     ,bbb            ,ddsdd,asdasdadsadsadad,sad~|@%asdasd

a2       ,a3          ,a4     ,a5      ,a6             ,

[ 本帖最后由 zhangshebao 于 2009-4-21 00:03 编辑 ]

论坛徽章:
0
23 [报告]
发表于 2009-04-21 07:52 |只看该作者
  1. awk '{v="@#%";print gensub(/([^\|]*)\|([^\,]*)\,([^\,]*)\,([^\,]*)\,([^\,]*)\,([^\,]*)\,(.*)/,"\\2"v"\\3"v"\\4"v"\\5"v"\\6"v"\\7",1)}' file|awk -F "@#%" '{printf "%-9s,%-12s,%-7s,%-8s,%-15s,%-300s\n",$1,$2,$3,$4,$5,$6}'
复制代码


为防止数据中有跟FS相同的内容而造成错误,最好把变量v=@#%搞的再特殊一点,多输些内容

result
  1. 32444    ,asd         ,42     ,345sa   ,asda5445       ,asdsa|,asdaas,,asd,,,asdadsad||sadad,sad~@%asdasd32432|                                                                                                                                                                                                                                                     
  2. as2d     ,421         ,3452sa ,asda2544,asd121sa       ,erasdaaaas,asdasdadsadsadad,sad~|@%asdasdasdsda|                                                                                                                                                                                                                                                            
  3. aspp2d   ,ass         ,23     ,aaa     ,bbb            ,ddsdd,asdasdadsadsadad,sad~|@%asdasd                                                                                                                                                                                                                                                                        
复制代码


就是不知楼主的awk有无gensub

[ 本帖最后由 ywlscpl 于 2009-4-21 08:04 编辑 ]

论坛徽章:
0
24 [报告]
发表于 2009-04-21 08:08 |只看该作者
[root@Greendays lianshou]# cat x
3453343|32444,asd,42,345sa,asda5445,asdsa|,asdaas,,asd,,,asdadsad||sadad,sad~@%asdasd32432|
232|as2d,421,3452sa,asda2544,asd121sa,erasdaaaas,asdasdadsadsadad,sad~|@%asdasdasdsda|
ab2|aspp2d,ass,23,aaa,bbb,ddsdd,asdasdadsadsadad,sad~|@%asdasd
[root@Greendays lianshou]# sed  -n 's/^[a-z,A-Z,0-9]*|//p' x | awk -F, '{printf "%-9s,%-12s,%-7s,%-8s,%-15s\n", $1,$2,$3,$4,$5}' >aakk
[root@Greendays lianshou]# sed  -n 's/^[a-z,A-Z,0-9]*|//p' x | sed 's/[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,//g' | cut -c 1-300 >aall
[root@Greendays lianshou]# cat aakk
32444    ,asd         ,42     ,345sa   ,asda5445      
as2d     ,421         ,3452sa ,asda2544,asd121sa      
aspp2d   ,ass         ,23     ,aaa     ,bbb            
[root@Greendays lianshou]# cat aall
,asdadsad||sadad,sad~@%asdasd32432|
erasdaaaas,asdasdadsadsadad,sad~|@%asdasdasdsda|
ddsdd,asdasdadsadsadad,sad~|@%asdasd
[root@Greendays lianshou]# paste aakk aall
32444    ,asd         ,42     ,345sa   ,asda5445        ,asdadsad||sadad,sad~@%asdasd32432|
as2d     ,421         ,3452sa ,asda2544,asd121sa        erasdaaaas,asdasdadsadsadad,sad~|@%asdasdasdsda|
aspp2d   ,ass         ,23     ,aaa     ,bbb             ddsdd,asdasdadsadsadad,sad~|@%asdasd

[ 本帖最后由 greendays 于 2009-4-21 08:09 编辑 ]

论坛徽章:
0
25 [报告]
发表于 2009-04-21 09:53 |只看该作者
原帖由 blackold 于 2009-4-20 20:38 发表
不要趁我吃饭才改啊, try:awk -F "[,|]" '{s=$0;sub(/[^|]*\|[^|]*,/,"",s); printf "%-9s,%-12s,%-7s,%-8s,%-15s,%-300s\n", $2,$3,$4,$5,$6,s}' test.dat

-F "[,|]" 是什么意思啊?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
26 [报告]
发表于 2009-04-21 10:08 |只看该作者
原帖由 zhangshebao 于 2009-4-20 23:45 发表
主要特点:
1、第7列数据中的逗号及|不处理
2、可以输出异常数据,如示例用555的这一行合法数据,666的这一行少一个数据列,为异常数据,仅输出到异常数据中
3、可以调试
4、如果对异常数据也想正常输出,改 ...

赞一下!用数组match的思路很好,不会像用-F[|,]那样破坏字段7。如果楼主有gawk就万事大吉了。看了一个nawk的文档,似乎match函数只支持两个参数。楼主也许该换台机器做,或者安装gawk。

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
27 [报告]
发表于 2009-04-21 11:19 |只看该作者

回复 #26 woodie 的帖子

不重建$0,-F[|,]也不会破坏$7。

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
28 [报告]
发表于 2009-04-21 11:24 |只看该作者

回复 #25 jakepain 的帖子

指定正则[|,]为FS。

论坛徽章:
0
29 [报告]
发表于 2009-04-21 11:29 |只看该作者
perl的split与pack功能解决这应该很方便的
perl -lne 'chomp;@fields=split /\|/,$_,2;@fields=split /,/,$fields[1],6;print pack("A9A12A7A8A15A300",@fields);' file

论坛徽章:
0
30 [报告]
发表于 2009-04-21 11:31 |只看该作者
原帖由 blackold 于 2009-4-21 11:24 发表
指定正则[|,]为FS。

没用过,难道可以指定两个分隔符?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP