shell 实现对Hive表字段脱敏写入新表

发布于:2024-04-25 ⋅ 阅读:(21) ⋅ 点赞:(0)

数据安全管理,本shell 实现对hive源表敏感字段进行md5加密,然后写入新表;

read -p 交互输入:要脱敏的hive表、分区,示例: test_db.table_name 20240331

生成更新hive分区表的hql: insert overwrite table xxx

备注:仅供参考,可对本shell代码,做进一步修改调整,满足自己的需求。

#!/bin/bash
# 2024.04.19
read -p "请按示例格式输入要脱敏的hive表、分区,示例: test_db.table_name 20240331 ### " table etl_date

#获取库名、表名,存入变量
dbname=`echo $table |awk -F. '{print $1}'`
tbl=`echo $table |awk -F. '{print $2}'`

target_db=import_db

#首先判断目标表是否存在
hdfs dfs -test -e /user/hive/warehouse/${target_db}.db/$tbl
if [ $? -eq 0 ] ;then
    echo "${target_db}.$tbl 目标库已经存在...,请确认表结构是否与源表一致"

else

# 1、 在 ${target_db} like 建表
echo "1、 create table ${target_db}.$tbl like $table;"
beeline -e "create table ${target_db}.$tbl like $table;"


# 2、 把hive表,所有字段 切出来 备用
beeline --showHeader=false --outputformat=tsv2 -e "desc $table" |awk '{print $1}' >desc_field.out
echo "desc $table .... beeline ok"


#############################################md5表字段加密开始#############################################
num=`cat desc_field.out |grep NULL |wc -l`
if [ $num == 1 ] ;then
    # tac desc_field.out |sed -n '6,$p' |tac >desc_field_final.out
    cat desc_field.out |sed '/NULL/,$d' >desc_field_final.out
else
    cat desc_field.out >desc_field_final.out
fi


# 需要脱敏的敏感字段,手动添加维护
sensitive_fields=('name' 'phone' 'iden' 'tel')

fields=`cat desc_field_final.out`
m=`cat desc_field_final.out |wc -l`
flag=0

md5_fields=""
echo $md5_fields
# 嵌套循环,拿 表字段 与 敏感字段 进行匹配,表字段如果是敏感字段,进行MD5 加密,拼接 sql 字符串
for j in $fields
do
	biaoji=1
	# 1.匹配到,进行md5加密,拼接;标记置为0,跳出内循环;2.没有匹配到,继续下一轮内循环;
	length=${#sensitive_fields[*]}
	# length 控制内循环的次数
	for ((i=0;i<${length};i++))
	do
		echo "i=$i"
		if [ $j == ${sensitive_fields[i]} ]
		then
			md5_fields=${md5_fields}",md5($j) as $j"
			biaoji=0
			break
		else
			continue
		fi
	done
	# 内循环执行一轮结束,对 biaoji 的值进行判断,为1,说明 表字段 非敏感字段,进行拼接
	if [ $biaoji == 1 ]
	then
		md5_fields=${md5_fields}","$j
	fi
	echo $md5_fields
	
	((flag++))
	echo "flag=$flag"
	# 外循环次数 等于 表字段数,外循环完成,拼接 md5_fields 完成
	if [ $flag -eq $m ]
	then
		# 删除 md5_fields 串里第一个逗号,正确的 md5_fields 拼接完成
		md5_fields=`echo $md5_fields | sed 's/,//'`
		echo $md5_fields
	fi
	
done
#############################################md5表字段加密结束#############################################

#############分区###############
in_values="'$etl_date'"
echo "in_values=$in_values"

# in_values=""
# for i in 20240131,20240228,20240331
# do
#     in_values=$in_values",'$j'"
# done
# # ,'20240131','20240228','20240331'
# in_values=`echo $in_values |sed 's/,//'`
# # '20240131','20240228','20240331'
# echo "in_values=$in_values"
###############分区###############




# 3、对分区字段个数计数 如果是分区表,取出分区字段
partition_field_num= `sed -n '/#/,$p' desc_field.out |grep ^[^#] |wc -l`
echo "partition_field_num=$partition_field_num"

sql="insert overwrite table $target_db.$tbl "
echo "初始:$sql"


# 4、生成更新分区数据的语句;分区字段个数不同,生成不同的 insert overwrite table
if [ $partition_field_num -eq 2 ];then
    partition1=$(echo `sed -n '/#/,$p' desc_field.out |grep ^[^#]` |awk '{print $1}')
    partition2=$(echo `sed -n '/#/,$p' desc_field.out |grep ^[^#]` |awk '{print $2}')
    sql=$sql"partition($partition1,$partition2) select $md5_fields from $table where $partition1 in ($in_values);"
    echo "拼接2个分区后:$sql"

elif [ $partition_field_num -eq 1 ];then
    partition1=$(echo `sed -n '/#/,$p' desc_field.out |grep ^[^#]` |awk '{print $1}')
    sql=$sql"partition($partition1) select $md5_fields from $table where $partition1 in ($in_values);"
    echo "拼接1个分区后:$sql"

else
    sql=$sql"select $md5_fields from $table;"
    echo "无分区:$sql"

fi



# 5、生成 update_partitions.sql
cat <<-'EOF' >update_partitions.sql
set hive.execution.engine=tez;
set tez.queue.name=root.default;
set hive.tez.java.opts=-Xmx6144m;
set hive.tez.container.size=8192;
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.dynamic.partitions.pernode=1000;
EOF
echo "$sql" >>update_partitions.sql


fi