1、背景
Windows系统和Linux系统的行结束符不同。在Windows系统中,行结束符使用的是CRLF(Carriage Return + Line Feed,即\r\n),而在Linux系统中,行结束符使用的是LF(Line Feed,即\n)。当在Windows环境中编辑并上传文件到Linux环境中运行时,如果文件的行结束符被转换为Windows风格的CRLF,那么在Linux中执行该文件时可能会出现错误,因为Linux系统的shell解释器会将换行符视为命令的结束标志。因此,如果文件在Windows环境中修改并上传,格式被转换为MS-Dos格式(即CRLF),这样的文件在Linux中运行会出错。
2、规避DOS换行符
2.1 函数封装
函数名称:public.data_load;
入参:
| 参数名称 | 描述 | 样例 |
|---|---|---|
| dir | 文件路径。 | path |
| filename | 文件名称。 | filename.txt |
| loadtype | 加载方式(replace/insert)。 | insert |
| schemaname | 表模式名。 | table_schema |
| tablename | 表名称。 | table_name |
| filedelimiter | 文件分隔符。 | | |
返回值:0表示成功,1表示失败 。
2.2 底层实现
create or replace function public.data_load (
IN dir text,
IN filename text,
IN loadtype text,
IN schemaname text,
IN tablename text,
IN filedelimiter text
) RETURNS TEXT AS
$$
BEGIN
……
……
—匹配换行符非二进制
str_sql:=’
CREATE readable EXTERNAL WEB TABLE ‘||V_SNAME||’.‘||external_web_table_name||’
(rt text)
execute ‘’/tmp/ext_script/GetFileType.sh ‘||dir||’ ‘||filename||’ ‘’ on master format ‘‘text’’ (delimiter ‘’|‘’)‘;
execute str_sql;
str_sql=‘select rt from ‘||V_SNAME||’.’||external_web_table_name;
execute str_sql into ret;
IF ret = 0 THEN
external_newline :=‘LF’;
ELSE
external_newline :=‘CRLF’;
END IF;
……
……
—给系统传换行符的类型,系统自动适配
LOCATION := ‘LOCATION (’’’ || dir || ‘/’ || filename || E’‘’) \nFORMAT ‘‘text’’ (DELIMITER ‘’’ || filedelimiter || ‘’’ NULL ‘’‘’ ESCAPE ‘‘off’’ NEWLINE ‘’‘||external_newline||’‘’ )‘;
RAISE INFO ‘%’, LOCATION;
str_sql = ‘CREATE READABLE EXTERNAL TABLE ‘|| V_SNAME ||’.’|| external_table_name || E’\n(\n ‘||ddl_body || E’\n) \n’ || LOCATION ;
EXECUTE str_sql ;
……
END;
$$LANGUAGE plpgsql;
vi /tmp/ext_script/GetFileType.sh
#!/bin/bash
set -o errexit
dir=$1
filename=$2
hdfs dfs -ls dir/{dir}/dir/{filename} |sort -k 5 -n -r| awk ‘{print $NF}’|while read line
do
DOS_Count=hdfs dfs -cat $line |grep -v '匹配到二进制文件'| grep -U $'\x0D'|wc -l
echo $DOS_Count
break
done
2.3 测试入库DOS格式换行符文件
2.3.1 创建表
create table table1
(
deal_date char(10),
area_code char(10)
);
2.3.2 创建入库文件
20240101|000
20240101|111
20240101|222
20240101|333
2.3.3 装载测试
select public.data_load(‘hdfs://path’,‘filename.txt’,‘insert’,‘xxxxx’,‘xx_xx_xx_xxxx_xxx’,‘|’);
2.3.4 测试结果
场景一:不规避DOS换行符测试

场景二:规避DOS换行符测试


被折叠的 条评论
为什么被折叠?



