【问题标题】:To ignore Pipe in pipe delimited file忽略管道分隔文件中的管道
【发布时间】:2013-08-11 17:22:14
【问题描述】:

我有一个分隔| 的文件,我需要在其中搜索第 3 列中的字符并将其替换为 null。我只需要替换第三个字段中出现字符的列。

file1.txt

xx|yy|xx|12

输出文件:

xx|yy||12

我通过这个实现了

awk 'BEGIN {FS=OFS="|" } $3 ~ /[[:alnum:]]/ { $3="" }1' file

但我面临的是,如果有任何列具有管道字符,应将其视为单列,则不应将其视为字段分隔符。

xx|yy|"xyz|xx"|AAA|12...

所以输出应该是这样的:

xx|yy|"xyz|xx"||12

所以考虑到 AAA 作为第 4 列,AAA 应该替换为 null。

【问题讨论】:

  • 这个问题似乎跑题了,因为它属于Unix & Linux
  • @Cole"Cole9"Johnson 你错了。 awk 编程是 Stack Overflow 上的完美话题,尽管如果你足够努力的话,当然可以写出离题的 awk 问题。

标签: shell unix csv awk


【解决方案1】:

对于GNU awk,您需要使用FPAT 来描述字段是什么,而不是使用FS 来描述字段分隔符是什么。例如:

$ cat file
xx|yy|AAA|12
xx|"yy|xx"|AAA|12

$ awk '{$3=""}1' OFS='|' FPAT='([^|]+)|("[^"]+")' file
xx|yy||12
xx|"yy|xx"||12

但是,您最好使用具有CSV parsing 模块的高级语言,例如python。

【讨论】:

    【解决方案2】:

    我喜欢@sudo_O 的回答,我只是不确定它为什么会起作用,因为"yy 满足 FPAT RE [^|]+ 的第一部分,所以我不知道为什么 gawk 不会认为这是一个字段而不是推迟并将其视为与 FPAT 的第二部分 "[^"]+" 匹配的较大 "yy|xx" 的一部分。

    无论如何,如果您没有 gawk,您可以随时将字段之间或引用字段内的“FS”更改为其他字符(例如 \t),然后再对您的输入进行操作,只需将 " 视为FS 最初:

    $ cat file
    xx|yy|"xyz|xx"|AAA|12
    
    $ awk 'BEGIN{FS=OFS="\""} {for (i=1;i<=NF;i+=2) gsub(/\|/,"\t",$i)}1' file
    xx      yy      "xyz|xx"        AAA     12
    
    $ awk 'BEGIN{FS=OFS="\""} {for (i=2;i<=NF;i+=2) gsub(/\|/,"\t",$i)}1' file
    xx|yy|"xyz      xx"|AAA|12
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      • 2020-08-14
      • 1970-01-01
      • 2019-07-15
      • 2013-04-04
      • 1970-01-01
      相关资源
      最近更新 更多