使用sed替换NULL列

时间:2013-12-31 11:00:44

标签: sed hive

我正在使用hive命令从Hive导出数据,它输出一个纯文本文件,以\ t结尾的字段和以\ n终止的行。

假设有一些NULL列,还有一些值中的'NULL'字符,如下所示:

NULL    NULL    NULL
ABCD    ABCDNULLABCD    ABCD-NULL-ABCD

我使用sed命令将NULL替换为\ N(用于加载到MySQL中):

hive -f query.sql | sed 's/\bNULL\b/NULL/g' >data.txt

结果是:

\N  \N  \N
ABCD    ABCDNULLABCD    ABCD-\N-ABCD

所以问题是,对于\ b修饰符,' - '也匹配,' - '之间的NULL被替换。

有什么方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

正如我在评论中指出的,我更喜欢其他工具,但也可以使用循环来解决它。它会重复替换命令,直到它失败:

sed ':a; s/\(^\|\t\)NULL\(\t\|$\)/\1\\N\2/; t a' infile

它产生:

\N      \N      \N
ABCD    ABCDNULLABCD    ABCD-NULL-ABCD

答案 1 :(得分:2)

首先,让我们创建一个示例以包含所有可能的极端情况:

$ cat >sample.txt
NULL    NULL    NULL
ABCD    ABCDNULLABCD    ABCD-NULL-ABCD
ABCDNULL    x   NULLABCD
^D

(空格有标签)

我认为为此目的使用预见和后视正则表达式是最干净的,例如使用perl

$ perl -pe 's/((?<=\t)|^)NULL($|(?=\t))/\\N/g' sample.txt
\N  \N  \N
ABCD    ABCDNULLABCD    ABCD-NULL-ABCD
ABCDNULL    x   NULLABCD

如果您真的更喜欢sed,可以使用@Birei的解决方案,它会提供相同的输出。

答案 2 :(得分:1)

您没有提到您正在使用的sed版本。以下几乎适用于所有变体:

sed 's_^NULL\t_\\N\t_;s_\tNULL$_\t\\N_;s_\tNULL\t_\t\\N\t_g'

为了清晰起见,这使用了下划线_而不是典型的斜杠/

sed的某些版本(例如IIRC HPUX 10.20)上,您需要将\t替换为实际制表符。