我正在使用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被替换。
有什么方法可以解决这个问题吗?
答案 0 :(得分:2)
正如我在评论中指出的,我更喜欢其他工具,但sed也可以使用循环来解决它。它会重复替换命令,直到它失败:
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
替换为实际制表符。