免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
41 [报告]
发表于 2011-08-11 21:26 |只看该作者
非常实用的一个帖子,不要沉了呀

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
42 [报告]
发表于 2011-08-12 01:29 |只看该作者
本帖最后由 yinyuemi 于 2011-08-12 03:00 编辑

回复 41# hfvbc
  1. echo '1,"nihao,shia,"shi","hiscihe",3,8
  2. 1,"nihao,shma",shi","hiscihe",3,8
  3. 1,"nihao,"shma",shi","hiscihe",3,8
  4. 1,"nihao,s"hma",shi","hiscihe",3,8
  5. 2,1,"nihao,shma",shi",2,5,6,"hiscihe",3,8,9' |\
  6. awk -F, -v t="#" '{
  7.         printf $1;
  8.         for(i=2;i<=NF;i++){
  9.                 if(j==0){
  10.                         if($i~/^\"[a-zA-Z]+$/){sub("\"","",$i);printf t $i",";j++}
  11.                         else{gsub("\"","",$i);printf t $i}
  12.                 }else{
  13.                         if($i~/[a-zA-Z ]+\"$/&&$(i+1)~/^\"[a-zA-Z]|[0-9]/){sub("\"$","",$i);printf $i;j--}
  14.                         else {printf $i","}
  15.                 }
  16.         }
  17.         print ""}'
  18. 1#nihao,shia,"shi#hiscihe#3#8
  19. 1#nihao,shma",shi#hiscihe#3#8
  20. 1#nihao,"shma",shi#hiscihe#3#8
  21. 1#nihao,s"hma",shi#hiscihe#3#8
  22. 2#1#nihao,shma",shi#2#5#6#hiscihe#3#8#9
复制代码

论坛徽章:
0
43 [报告]
发表于 2011-08-12 17:15 |只看该作者
awk的语法:
awk [-F re] [parameter...] ['program'] [-f 'programfile'] [in_file_list]


awk里面的BEGIN,END结构:
BEGIN和END中的语句分别在开始读取文件(in_file)之前和读取完文件之后发挥作用,可以理解为初始化和扫尾。

awk里面的if..else;   while ; do..while; for; break; continue; printf 语法都和C语言的语法一致;而且awk支持使用if (key in array)这样的判断语句(其中,array是数组,这一点和python的语法非常相像。);awk支持使用for (key in array)这样的语法来遍历数组(也是和python的语法很相像。)

论坛徽章:
0
44 [报告]
发表于 2011-08-12 18:51 |只看该作者
--------------------------------------------------------------------------------


说明:
本数据是用逗号分割的,部分字段是用引号引起来的,在引号中的字段算一个域,所以它的内容不能改变的

论坛徽章:
0
45 [报告]
发表于 2011-08-12 18:51 |只看该作者
另外,我的分割符号如果是一个变量呢?这个变量可能只有一位,可能有2位等,那么这个代码该怎么写呢?
非常感谢您.

论坛徽章:
0
46 [报告]
发表于 2011-08-12 23:14 |只看该作者
看来档次太低,你发的问题连意思都没看懂

论坛徽章:
0
47 [报告]
发表于 2011-08-13 10:54 |只看该作者
逗号分隔,如果双引号内要表示双引号,那么用两个双引号代替

输入
sdf,sdaf"asd""""""asd","asd"
输出
sdf<$>sdafasd"""asd<$>asd
  1. perl -pe 'BEGIN{$sep=q{<$>}}$s="";/(?:([^",]+)(?{$s.=$1})|"(?:([^"])(?{$s.=$2})|""(?{$s.=q{"}}))*"|,(?{$s.=$sep}))+/;$_=$s;'
复制代码
请根据需要修改 $sep

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
48 [报告]
发表于 2011-08-13 13:50 |只看该作者
回复 47# MaskRay


    可否加个注释?多谢!

论坛徽章:
0
49 [报告]
发表于 2011-08-13 15:33 |只看该作者
回复 48# yinyuemi

    被你点名到,荣幸之至……
    perl -pe 'BEGIN{$sep=q{<$>}}   $s="";/(?[^",]+)(?{$s.=$1})   |   "(?[^"])(?{$s.=$2})|""(?{$s.=q{"}}))*"  |  ,(?{$s.=$sep}))+/x;$_=$s;'

输入分成三类,代码中用  |  分隔开了
一类是非双引号非逗号即 [^",]+,这类直接输出,这里用了 Perl 正则内嵌代码的功能,(?{$s.=$1}) 即把 $1 追加到 $2
一类是逗号,这类输出分隔符
一类是双引号内的文本。假设碰到了开双引号,处理之后的文本时,如果是非双引号字符,那么也是直接输出;如果是连续两个双引号,只能输出一个;如果只有一个双引号,那么结束。这里需要对单个还是双个进行区分,所以使用了 Perl 正则中的 look-ahead,即 (?=),碰到双引号时检查下一个字符是否为双引号。

论坛徽章:
0
50 [报告]
发表于 2011-08-13 21:04 |只看该作者
回复 48# yinyuemi


   
被你点名到,荣幸之至。

输入分成三类:

  - 非双引号非逗号即 [^",]+,这类直接输出,这里用了 Perl 正则内嵌代码的功能,(?{$s.=$1}) 即把 $1 追加到 $2。
    这一部分对应到正则表达式中的

        (?[^",]+)(?{$s.=$1})

    由一对 `non-capturing parentheses` 即 `(?` 包起来,里面先是模式,然后跟着的是 `Perl` 正则表达式内嵌代码即 `(?{})`,用来把匹配的串追加到 `$2` 末尾。
  - 逗号,这类输出分隔符
    对应

        ,(?{$s.=$sep})

  - 双引号内的文本,碰到开双引号后,碰到非双引号字符则直接输出,否则用两个双引号转义,碰到单个双引号则结束。这类用 `"(([^"])|""*"` 表示。
    对应

        "(?[^"])(?{$s.=$2})|""(?{$s.=q{"}}))*"`
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP