【问题标题】:How to add ; at the end of each "show create table"如何添加;在每个“显示创建表”的末尾
【发布时间】:2019-07-25 14:56:08
【问题描述】:

所以,我有一个 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 脚本)。

【问题讨论】:

  • 如果你的文件格式没有改变并且transient总是在需要添加之前出现在行中,你可以简单地使用sed来添加它们sed '/transient/s/$/;/' file
  • 我是 shell 脚本的新手。您知道如何将其合并到上面的代码中吗?
  • 文本文件名是什么?生成文本文件后,您可以将其放置在脚本中的任何位置。 (根据它的生成方式,您甚至可以通过sed 命令将生成文本文件的任何内容的输出通过管道输出并写出成品)为什么在tables 被填充后要执行tab_list=`echo "${tables}"?你只是在强迫分词发生?
  • 文本文件名为aa.sql。我可以和你聊天吗?
  • 当然,只要我们中的一个人看到“继续聊天”按钮(并不总是显示),我很高兴与您聊天。你可以做什么添加sed '/transient/s/$/;/' aa.sql,这将在')'之后添加';'

标签: regex python-3.x shell unix hive


【解决方案1】:

根据我们在聊天中的讨论,讨论的两个解决方案如下:

如果您的格式是一致的并且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');

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

【讨论】:

    猜你喜欢
    • 2019-06-07
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多