【问题标题】:Using pipe character as a field separator使用管道字符作为字段分隔符
【发布时间】:2021-05-17 20:20:25
【问题描述】:

我正在尝试不同的命令来处理 csv 文件,其中分隔符是管道 | 字符。

虽然当逗号是分隔符时这些命令确实有效,但当我用管道替换它时会引发错误:

awk -F[|] "NR==FNR{a[$2]=$0;next}$2 in a{ print a[$2] [|] $4 [|] $5 }" OFS=[|] file1.csv file2.csv

awk "{print NR "|" $0}" file1.csv

我试过了,"|"[|]/| 无济于事。

我在 Windows 上使用 Gawk。我错过了什么?

【问题讨论】:

  • 您是否尝试过\|,例如awk -F\| '{ print NF }' bar.txt
  • 您的数据是什么样的?错误是什么?
  • 这是您的print 的问题。正如我在回答中指出的那样,只需使用逗号分隔字段即可。
  • 您尝试使用"|" 不起作用,因为您所做的只是关闭引号,然后放置一个未转义的管道,然后重新打开它们。您需要使用不同的引号:awk '{ print NR "|" $0}'/| 不起作用,因为那甚至不是转义字符!

标签: awk gawk


【解决方案1】:

您尝试过"|"[|]/|/| 不起作用,因为转义字符是\,而[] 用于定义字段范围,例如[,-],如果您希望FS,-

为了让它工作"|" 很好,你确定你是这样用的吗?或者,转义它 --> \|:

$ echo "he|llo|how are|you" | awk -F"|" '{print $1}'
he
$ echo "he|llo|how are|you" | awk -F\| '{print $1}'
he
$ echo "he|llo|how are|you" | awk 'BEGIN{FS="|"} {print $1}'
he

但请注意,当你说:

print a[$2] [|] $4 [|] $5

所以你根本没有使用任何分隔符。正如您已经定义了OFS,请执行以下操作:

print a[$2], $4, $5

例子:

$ cat a
he|llo|how are|you
$ awk 'BEGIN {FS=OFS="|"} {print $1, $3}' a
he|how are

【讨论】:

    【解决方案2】:

    对于多年后发现的任何人:总是引用壳元字符!

    我认为 gawk (GNU awk) 特别对待 |,所以应该引用它(对于 awk)。 OP 对[|] 拥有此权利。然而[|] 也是一个shell 模式。至少在bash 中,只会扩展 if 它匹配当前工作目录中的文件:

    $ cd /tmp
    $ echo -F[|]    # Same command
    -F[|]
    $ touch -- '-F|'
    $ echo -F[|]    # Different output
    -F|
    $ echo '-F[|]'  # Good quoting
    -F[|]           # Consistent output
    

    应该是这样的:

    awk '-F[|]'
    # or
    awk -F '[|]'
    

    awk -F "[|]" 也可以,但是 IMO 仅在您有实际扩展的内容时才使用软引号 (")(或者字符串本身包含硬引号 ('),它不能嵌套在任何方式)。

    请注意,如果这些字符位于未引用的变量中,也会发生同样的情况。

    如果 textvariable 包含或可能包含:[]?*,引用它,或 set -f 以关闭路径名扩展(单个不匹配的正方形支架在技术上是可以的,我认为)。

    如果 变量 包含或可能包含 IFS 字符(默认为空格、制表符、换行符),请引用它(除非您想要将其拆分)。或者 export IFS= 首先(承担后果),如果引用是不可能的(例如,一个疯狂的 eval)。

    注意:无论 IFS 为何,原始文本始终由空格分隔。

    【讨论】:

      【解决方案3】:

      尝试逃避|

      echo "more|data"  | awk -F\| '{print $1}'
      more
      

      【讨论】:

        【解决方案4】:

        您可以将| 转义为\|

        $ cat test
        hello|world
        $ awk -F\| '{print $1, $2}' test
        hello world
        

        【讨论】:

          猜你喜欢
          • 2012-02-19
          • 1970-01-01
          • 2013-02-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多