所以,我有一个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 + ";\n\n" >> ${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脚本)。
答案 0 :(得分:3)
在聊天中讨论之后,讨论的两个解决方案如下:
如果您的格式是一致的,并且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
GNU awk
具有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');
如果您还有其他问题,请告诉我。