【问题标题】:Append and replace using awk/sed使用 awk/sed 追加和替换
【发布时间】:2016-10-30 16:09:31
【问题描述】:

我有这个文件:

2016,05,P,0002    ,CJGLOPSD8                                                    
00,BBF,BBDFTP999,051000100,GBP,   ,       -2705248.00                           
00,BBF,BBDFTP999,059999998,GBP,   ,       -3479679.38                           
00,BBF,BBDFTP999,061505141,GBP,   ,             -0.40                           
00,BBF,BBDFTP999,061505142,GBP,   ,        6207621.00                           
00,BBF,BBDFTP999,061505405,GBP,   ,             -0.16                           
00,BBF,BBDFTP999,061552000,GBP,   ,             -0.24                           
00,BBF,BBDFTP999,061559010,GBP,   ,             -0.44                           
00,BBF,BBDFTP999,062108021,GBP,   ,             -0.34                           
00,BBF,BBDFTP999,063502007,GBP,   ,             -0.28  

我想以编程方式(在 unix 或 informatica 中,如果可能)获取顶行中的前两个字段,将它们连接起来,将它们附加到每行的末尾并删除第一行。

像这样:

00,BBF,BBDFTP999,051000100,GBP,,-2705248.00,201605                          
00,BBF,BBDFTP999,059999998,GBP,,-3479679.38,201605                           
00,BBF,BBDFTP999,061505141,GBP,,-0.40,201605                           
00,BBF,BBDFTP999,061505142,GBP,,6207621.00,201605                           
00,BBF,BBDFTP999,061505405,GBP,,-0.16,201605                           
00,BBF,BBDFTP999,061552000,GBP,,-0.24,201605                          
00,BBF,BBDFTP999,061559010,GBP,,-0.44,201605                         
00,BBF,BBDFTP999,062108021,GBP,,-0.34,201605                        
00,BBF,BBDFTP999,063502007,GBP,,-0.28,201605

这是我目前的尝试:

awk -vvar1=`cat OF\ OPSDOWN8.CSV | head -1 | cut -d',' -f1` -vvar2=`cat OF\ OPSDOWN8.CSV | head -1 | cut -d',' -f2` 'BEGIN {FS=OFS=","} {print $0, var 1var2}' OF\ OPSDOWN8.CSV> OF_OPSDOWN8.csv

有什么建议吗?我试过在论坛上四处寻找,但只能找到部分问题的答案。

感谢您的帮助。

【问题讨论】:

    标签: bash csv awk sed informatica


    【解决方案1】:

    使用这个awk

    awk 'BEGIN{FS=OFS=","} NR==1{val=$1$2;next} {gsub(/ */,"");print $0,val}' file
    

    说明:

    • BEGIN{FS=OFS=","} - 此块将 FS(字段分隔符)和 OFS(输出字段分隔符)设置为 ,
    • NR==1 - 使用行号 1。这里,$1$2 表示字段号。
    • print $0,val - 打印 $0(整行)并存储来自 val 的值。

    【讨论】:

    • 不需要将空白字符放在括号表达式中,它不是元字符。
    【解决方案2】:

    我会使用以下awk 命令:

    awk 'NR==1{d=$1$2;next}{$(NF+1)=d;gsub(/[[:space:]]/,"")}1' FS=, OFS=, file
    

    解释:

    • NR==1{d=$1$2;next} 应用于第 1 行并将变量 d(ate) 设置为第一个和第二个字段的值。处理剩余行时正在使用该变量。 next 告诉 awk 立即继续下一行,而不处理该行的进一步指令。

    • {$(NF+1)=d;gsub(/[[:space:]]/,"")}1 将一个新字段追加到该行(NF 是字段数,将d 分配给$(NF+1) 有效地添加了一个字段。gsub() 用于删除空格。@987654332最后的 @ 总是计算为 true 并让 awk 打印修改后的行。

    • FS=, 是命令行参数。它将输入字段分隔符设置为,

    • OFS=, 是一个命令行参数。它将输出字段分隔符设置为,

    输出:

    00,BBF,BBDFTP999,051000100,GBP,,-2705248.00,201605
    00,BBF,BBDFTP999,059999998,GBP,,-3479679.38,201605
    00,BBF,BBDFTP999,061505141,GBP,,-0.40,201605
    00,BBF,BBDFTP999,061505142,GBP,,6207621.00,201605
    00,BBF,BBDFTP999,061505405,GBP,,-0.16,201605
    00,BBF,BBDFTP999,061552000,GBP,,-0.24,201605
    00,BBF,BBDFTP999,061559010,GBP,,-0.44,201605
    00,BBF,BBDFTP999,062108021,GBP,,-0.34,201605
    00,BBF,BBDFTP999,063502007,GBP,,-0.28,201605
    

    【讨论】:

    • 当 2 个变量必须具有相同的值时,最好将它们一起设置为该值,而不是在程序的两端分别设置:awk 'BEGIN{FS=OFS=","}...
    • 虽然我通常同意,但我更喜欢在这种情况下保存 BEGIN 块。
    • 为什么?假设您有自己的理由,请考虑至少在使用它们之前将它们并排放置awk -F, -v OFS=, ...。而不是在脚本的两端。最后在文件列表中设置变量是违反直觉的,并且使编写需要解析文件名的脚本变得更加困难(例如,仅当您需要避免解释反斜杠和/或需要更改变量的值时才有用文件之间(例如awk '...' FS=, file1 FS=; file2.
    • @Elrodge 您正在使用旧的、损坏的 awk(Solaris 上的 /bin/awk)。如果您在 Solaris 上,请使用 /usr/xpg4/bin/awk 或 nawk,或者更好的是,获取/使用 GNU awk。
    • @EdMorton 你这个天才!使用 usr/xpg4/bin/awk 就像一个魅力。非常感谢。
    【解决方案3】:

    使用 sed :

    sed '1{s/\([^,]*\),\([^,]*\),.*/\1\2/;h;d};/.*/G;s/\n/,/;s/ //g' file
    

    在 ERE 模式下:

    sed -r '1{s/([^,]*),([^,]*),.*/\1\2/;h;d};/.*/G;s/\n/,/;s/ //g' file
    

    输出:

    00,BBF,BBDFTP999,051000100,GBP,,-2705248.00,201605
    00,BBF,BBDFTP999,059999998,GBP,,-3479679.38,201605
    00,BBF,BBDFTP999,061505141,GBP,,-0.40,201605
    00,BBF,BBDFTP999,061505142,GBP,,6207621.00,201605
    00,BBF,BBDFTP999,061505405,GBP,,-0.16,201605
    00,BBF,BBDFTP999,061552000,GBP,,-0.24,201605
    00,BBF,BBDFTP999,061559010,GBP,,-0.44,201605
    00,BBF,BBDFTP999,062108021,GBP,,-0.34,201605
    00,BBF,BBDFTP999,063502007,GBP,,-0.28,201605
    

    【讨论】:

      【解决方案4】:

      这可能对你有用(GNU sed):

      sed '1s/,//;1s/,.*//;1h;1d;s/ //g;G;s/\n/,/' file
      

      仅针对第一行:删除第一个逗号,从下一个逗号删除到行尾,将修改后的行存储在保持空间(HS)中,然后删除当前行(d 突然结束加工)。对于后续行:删除所有空格,附加 HS 并用逗号替换换行符(来自G 命令)。

      或者,如果您愿意:

      sed '1{s/,//;s/,.*//;h;d};s/ //g;G;s/\n/,/' file
      

      【讨论】:

        【解决方案5】:

        如果您想为此使用 Informatica,请使用两个源限定符。读取文件两次 - 在一个 SQ 中仅一行(过滤掉其余部分),在第二个 SQ 中读取除第一行之外的整个文件(跳过标题)。在虚拟端口上加入这两个,你就完成了。

        【讨论】:

          猜你喜欢
          • 2013-05-30
          • 2017-11-11
          • 2014-12-04
          • 1970-01-01
          • 2020-02-03
          • 1970-01-01
          • 2017-02-08
          • 2019-01-20
          • 2016-10-29
          相关资源
          最近更新 更多