免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 16436 | 回复: 52

awk问题求助[高人现身呀][db2 csv格式的数据转定分割符的数据] [复制链接]

论坛徽章:
0
发表于 2011-08-10 19:02 |显示全部楼层
本帖最后由 hfvbc 于 2011-08-11 16:41 编辑

源数据:
逗号分割,如果是字符型的就带有引号,如下:
cat a.txt
1,"nihao,shia,"shi","hiscihe",3,8
1,"nihao,sh ma",shi","hiscihe",3,8

变量a表示分割符,如果a=^|^,
变量b表示字段个数,如果b=5,
表结构如果是(n1 int, n2 char, n3 char, n4 int, n5 int) 则需要的目标数据为:
1^|^nihao,shia,"shi^|^hiscihe^|^3^|^8
1^|^nihao,sh ma",shi^|^hiscihe^|^3^|^8

可以用awk实现,也可以用其他的shell命令来实现,

解释:
1,可以理解为db2 del方式导出的数据需要转化成定分割符的数据,这个分割符不太确定,可以是一位,可以是二位等,在程序中需要用变量表示.
2,例子中的数据,分割符,字段个数,表结构全部是举例的,在实际程序中他们都是变化的。

是否可以换个思路:
1,以逗号为分割符,
2,如果类型是char等的,就必须以”开始,以“结束。
3,如果类型是char等的,但是它没有以”开始,则把这些类容归到上一个域。
4,如果是数据类型的,就只需要以,分割。
5,由于处理的数据量比较大,所以最好考虑效率问题
6,代码最好可以在aix,hp-unix,redhat等linux上运行。
我个人感觉,这个在引号的匹配上比较困难。


借鉴了一下jason680 的代码,大家看看这样的思路有没有什么问题 ,然后怎么充实呢 ?

##N中的0表示该字段类型是数值型,1表示该字段是字符型,长度表示是字段的个数。
awk -F',' -v K='^|^' -v D=","  -v N="01100"
  'function Err(e){print e" <--Error";next}
   {L=length(N)
      if(L==NF){   //数据不包含逗号
        for(n=0;n++<L{
           w=substr(N,n,1)
           if(w==1){   //字符型的
              去掉双引号,输出$n,输出分割符
            }
            else if(w==0){  //数值型的
             输出数字,输出分割符
            }
            else {
              Err("N is invalid"
            }
          }
       }
       else if(L<NF)  {  //字符型数据一定包含逗号,可能包含换行符号
         
       }      
       else {   // 字符型数据一定包含换行符,可能包含逗号
      
       }
    }'  filename

论坛徽章:
0
发表于 2011-08-10 19:44 |显示全部楼层
说明:
本数据是用逗号分割的,部分字段是用引号引起来的,在引号中的字段算一个域,所以它的内容不能改变的.

论坛徽章:
10
天蝎座
日期:2013-09-22 22:32:23程序设计版块每日发帖之星
日期:2016-08-07 06:20:00lufei
日期:2016-06-17 17:38:40程序设计版块每日发帖之星
日期:2016-06-12 06:20:002016科比退役纪念章
日期:2016-05-31 15:47:20CU十四周年纪念徽章
日期:2016-05-27 12:24:562015年亚洲杯之阿曼
日期:2015-05-03 21:01:352015年辞旧岁徽章
日期:2015-03-03 16:54:15天蝎座
日期:2013-10-20 21:05:24程序设计版块每日发帖之星
日期:2016-08-11 06:20:00
发表于 2011-08-10 20:04 |显示全部楼层

  1. awk -F"," -vOFS="^|^" '{NF+=0;print}'
复制代码

论坛徽章:
0
发表于 2011-08-10 20:41 |显示全部楼层
回复 3# liion631818


    谢谢你的回答,你的答案与我的需求有少许误差,
你的答案是:
[admin@dbs test]$ awk -F"," -vOFS="^|^" '{NF+=0;print}' a
1^|^"nihao^|^shia^|^"shi"^|^"hiscihe"^|^3^|^8
1^|^"nihao^|^shma"^|^shi"^|^"hiscihe"^|^3^|^8
我的要求是:
1^|^nihao,shia,"shi^|^hiscihe^|^3^|^8
1^|^nihao,shma",shi^|^hiscihe^|^3^|^8

如果在你的答案的基础上再加上引号的匹配就完美了.

论坛徽章:
0
发表于 2011-08-10 20:44 |显示全部楼层
本帖最后由 lionfun 于 2011-08-10 20:56 编辑

回复 1# hfvbc
你的问题比较特殊啊,我通过分几种情况去匹配了。写完这个sed,连我自己都看不懂!
  1. [root@M2_lion_S10_115.238.72.66_61618_A dir]# cat file1
  2. 1,"nihao,shia,"shi","hiscihe",3,8
  3. 1,"nihao,shma",shi","hiscihe",3,8
  4. [root@M2_lion_S10_115.238.72.66_61618_A dir]# sed -r 's/([^",][^",]+)",([^",][^",]+)/\1-ab-\2/g;s/([^",][^",]+),"([^",][^",]+)/\1-ba-\2/g;s/([^,][^,]+),([^,][^,]+)/\1-b-\2/g;s/","|",|,"|,/^|^/g;s/-ab-/",/g;s/-ba-/,"/g;s/-b-/,/g' file1
  5. 1^|^nihao,shia,"shi^|^hiscihe^|^3^|^8
  6. 1^|^nihao,shma",shi^|^hiscihe^|^3^|^8
  7. [root@M2_lion_S10_115.238.72.66_61618_A dir]# cat file2
  8. 1,"nihao,shia,"shi","hiscihe",3,8
  9. 1,"nihao,shma",shi","hiscihe",3,8
  10. 1,"nihao,"shma",shi","hiscihe",3,8
  11. 1,"nihao,s"hma",shi","hiscihe",3,8
  12. 2,1,"nihao,shma",shi",2,5,6,"hiscihe",3,8,9
  13. [root@M2_lion_S10_115.238.72.66_61618_A dir]# sed -r 's/([^",][^",]+)",([^",][^",]+)/\1-ab-\2/g;s/([^",][^",]+),"([^",][^",]+)/\1-ba-\2/g;s/([^,][^,]+),([^,][^,]+)/\1-b-\2/g;s/","|",|,"|,/^|^/g;s/-ab-/",/g;s/-ba-/,"/g;s/-b-/,/g' file2
  14. 1^|^nihao,shia,"shi^|^hiscihe^|^3^|^8
  15. 1^|^nihao,shma",shi^|^hiscihe^|^3^|^8
  16. 1^|^nihao,"shma",shi","hiscihe^|^3^|^8
  17. 1^|^nihao,s"hma",shi^|^hiscihe^|^3^|^8
  18. 2^|^1^|^nihao,shma",shi^|^2^|^5^|^6^|^hiscihe^|^3^|^8^|^9
  19. [root@M2_lion_S10_115.238.72.66_61618_A dir]#
复制代码

论坛徽章:
0
发表于 2011-08-10 20:49 |显示全部楼层
本帖最后由 shinyguo_s 于 2011-08-10 20:51 编辑

cat a.txt | tr -d '\"' | sed 's/,/\^\|\^/g'
先把引号去掉,再把,换成^|^

论坛徽章:
0
发表于 2011-08-10 20:55 |显示全部楼层
回复 6# shinyguo_s


    你一开始就tr -d 删除引号了,他的结果的引号怎么要回来?

论坛徽章:
0
发表于 2011-08-10 21:03 |显示全部楼层
回复 5# lionfun


感谢您,非常感谢您,您的代码运行出来的结果正是我想要的.
不过再进一步问您一下,您这个代码的效率怎么样呀?我可是要处理大量的数据呢?
呵呵,我之所以问您这个问题,不是我怀疑您的代码效率有问题,而是我看不太懂,呵呵.

论坛徽章:
0
发表于 2011-08-10 21:08 |显示全部楼层
回复 8# hfvbc
  1. 你自己运行看看吧,效率我觉得不是很好吧,因为用了很多的替换了!后面会有人给更好地答案的,你先等嘛……
复制代码

论坛徽章:
0
发表于 2011-08-10 21:10 |显示全部楼层
回复 5# lionfun


    另外,我的分割符号如果是一个变量呢?这个变量可能只有一位,可能有2位等,那么这个代码该怎么写呢?
非常感谢您.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP