使用管道字符作为字段分隔符

时间:2014-12-02 10:01:56

标签: awk gawk

我尝试使用不同的命令来处理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。我错过了什么?

4 个答案:

答案 0 :(得分:3)

您尝试了"|"[|]/|/|不起作用,因为转义字符为\,而[]用于定义一系列字段,例如[,-]如果您希望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

答案 1 :(得分:1)

尝试逃避|

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

答案 2 :(得分:1)

您可以将|转义为\|

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

答案 3 :(得分:1)

对于多年后发现此问题的任何人:始终引用外壳元字符!

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

$ 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 仅在您需要实际扩展某些内容时才使用软引号 (")(或字符串本身包含硬引号 ('),即不能以任何方式嵌套)。

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

如果 text变量 包含或可能包含:[]?*,引用它,或 set -f 以关闭路径名扩展(a我认为,单一的、不匹配的方括号在技术上是可以的)。

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

注意:无论 IFS 如何,原始文本总是被空格分割。