如何添加 ;在每个"show create table"结束时



所以,我有一个txt文件,其中包含以下内容:

CREATE EXTERNAL TABLE `table1`(
`tab_id bigint COMMENT 'The unique identifier of thetable')
ROW FORMAT SERDE 
*
STORED AS INPUTFORMAT 
* 
OUTPUTFORMAT 
*
LOCATION
*
TBLPROPERTIES (
'transient_lastDdlTime'='1556u3ehw27')
CREATE TABLE `table2`(
`count` bigint)
ROW FORMAT SERDE 
* 
STORED AS INPUTFORMAT 
*
OUTPUTFORMAT 
*
LOCATION
'hdfs://path/'
TBLPROPERTIES (
'transient'='15407')

如您所见,在每个表的 DDL 之后,在其末尾没有 ;。我正在尝试编写一个插入;在每个表 DDL 之后。所以输出应该是这样的:

CREATE EXTERNAL TABLE `table1`(
`tab_id bigint COMMENT 'The unique identifier of thetable')
ROW FORMAT SERDE 
*
STORED AS INPUTFORMAT 
* 
OUTPUTFORMAT 
*
LOCATION
*
TBLPROPERTIES (
'transient_lastDdlTime'='1556u3ehw27');
CREATE TABLE `table2`(
`count` bigint)
ROW FORMAT SERDE 
* 
STORED AS INPUTFORMAT 
*
OUTPUTFORMAT 
*
LOCATION
'hdfs://path/'
TBLPROPERTIES (
'transient'='15407');

我尝试过两种方法。(1)通过添加DDL创建脚本和python程序。

下面是我的 DDL 创建.sh脚本,它运行我的数据库的表并为数据库中的所有表生成单个文件。我尝试使用下面最后一行(# cat...)显示的cat函数来执行此操作,但不断收到错误。

hiveDBName=my_db;
showcreate="show create table "
showpartitions="show partitions "
terminate=";"
tables=`hive -e "use $hiveDBName;show tables;"`
tab_list=`echo "${tables}"`
rm -f ${hiveDBName}_all_table_partition_DDL.sql
for list in $tab_list
do
echo "Generating table script for " ${hiveDBName}.${list}
showcreatetable=${showcreatetable}${showcreate}${hiveDBName}.${list}${terminate}
done
echo " ====== Create Tables ======= : " $showcreatetable
##Remove the file
rm -f ${hiveDBName}_extract_all_tables.txt
hive -e "use $hiveDBName; ${showcreatetable}" > /home/path/filter_ddls/aa.sql
grep -v "WARN" /home/path/filter_ddls/aa.sql >/home/path/hive_db_ddls/${hiveDBName}_extract_all_tables.sql
# cat a1.sql + ";nn" >> ${hiveDBName}_extract_all_tables.sql

下面是我的Python程序,但此方法的输出仅在跳过某些表的tblproperties之后添加;。

import re
f = open("/home/path/ddl.sql", 'rt', encoding='latin-1').read()
with open("/home/path/new_ddl.sql","w") as output:
output.write(re.sub(r'(TBLPROPERTIES (.*?))', r'1;', f, flags=re.DOTALL))

有什么想法或建议可以实现这一目标吗?最好是第一个选项(.sh脚本)。

在聊天中讨论之后,讨论的两个解决方案如下:

如果您的格式一致,并且transient始终出现在末尾需要结束';'的行中,那么只需要一个简单的sed替换,例如

sed '/transient/s/$/;/' file

(添加-i选项以就地编辑文件,和/或添加-i.bak以就地编辑,保留原始文件不变,扩展名为.bak)

另一方面,如果内容可能会更改并且transient可能存在也可能不存在,那么您可以关闭TBLPROPERTIES标记,然后在文件中向前扫描以查找TBLPROPERTIES之后的第一个结束')'并在那里添加结束';'

awk提供了更强大的解决方案,因为没有保证TBLPROPERTIES和闭合')'之间可能的线路数量。下面awk与一个简单的变量一起使用,look服务器作为一个标志,指示您是否在TBLPROPERTIES(look=1)之后查找关闭')',或者不是(look=0)。

例如:

awk -v look=0 '
/^TBLPROPERTIES/ { look=1 }
look == 1 {
if ( sub (/[)]$/,");") )
look=0
}1
' file

GNUawk具有gawk -i inplace扩展名,允许就地编辑文件,类似于sed,否则您只需将输出重定向到临时文件,然后复制或移动到原始文件名。

无论是使用上述sed还是awk,输出都具有所需的终止';',例如

CREATE EXTERNAL TABLE `table1`(
`tab_id bigint COMMENT 'The unique identifier of thetable')
ROW FORMAT SERDE
*
STORED AS INPUTFORMAT
*
OUTPUTFORMAT
*
LOCATION
*
TBLPROPERTIES (
'transient_lastDdlTime'='1556u3ehw27');
CREATE TABLE `table2`(
`count` bigint)
ROW FORMAT SERDE
*
STORED AS INPUTFORMAT
*
OUTPUTFORMAT
*
LOCATION
'hdfs://path/'
TBLPROPERTIES (
'transient'='15407');

如果您有其他问题,请告诉我。

最新更新