下面是场景
我有一个列表文件,其中有包含表名的列表文件(假设有 10 个表),还有另一个文件,其中所有创建的 DDL 大约为 100 个。
我需要从第二个文件中提取第一个文件中存在的表的 create DDLS。我已经使用sed
命令实现了这一点。但是,我遇到了一个问题,我的命令为几个表以及一些不在第一个文件中的额外表复制两次
对于前;
我的List_File.txt
有
ACASE
ABC
ABCH
CREATE_DDLS.txt
有
CREATE TABLE <SCHEMA_NAME>.ACASE
(
COLUMN1,
COLUMN2,
COLUMN3
) ;
CREATE TABLE <SCHEMA_NAME>.ACASE01
(
COLUMN1,
COLUMN2,
COLUMN3
) ;
CREATE TABLE <SCHEMA_NAME>.ACASE03
(
COLUMN1,
COLUMN2,
COLUMN3
);
CREATE TABLE <SCHEMA_NAME>.ABC
(
COLUMN1,
COLUMN2,
COLUMN3
) ;
CREATE TABLE <SCHEMA_NAME>.ABCD
(
COLUMN1,
COLUMN2,
COLUMN3
) ;
场景一:
ACASE 存在于列表文件中,第二个文件中有 ACASE/ACASE01/ACASE03,下面的命令复制所有三个表,我只需要 ACASE 创建 DDL 到输出。
场景2:
ABC 和 ABCD 存在于列表文件中,命令输出 ABCD 表两次,而我只需要一个 ABCD。
下面是我正在执行的命令
while read -r line
do
sed -n '/CREATE TABLE SCHEMANAME.TABLENAME/,/\;/p' Create DDLS file
done < List file > NewFile.txt
任何帮助是极大的赞赏。
谢谢
答案1
您的示例和/或尝试是错误的。
不管怎样,如果我拿你的示例文件,你的脚本可能是
while read -r line; do
sed -n "/CREATE TABLE <SCHEMA_NAME>.$line/,/;/p" CREATE_DDLs.txt ;
done < List_File.txt
它将匹配所有记录,因为ACASE
也会匹配ACASE01
.用作$
行结束的锚点:
while read -r line; do
sed -n "/CREATE TABLE <SCHEMA_NAME>.$line$/,/;/p" CREATE_DDLs.txt ;
done < List_File.txt
也就是说,对于较长的表列表,一遍又一遍地扫描整个文件并不是很有效,而使用扩展正则表达式,您可以搜索类似 的内容(ACASE|ABC|ABCH)
,因此将第一个文件放入正确的形式并在搜索中使用它图案:
TABLES=$(cat List_File.txt|tr '\n' '|')
sed -nE "/CREATE TABLE <SCHEMA_NAME>.(${TABLES%|})$/,/;/p" CREATE_DDLs.txt
将tr
用“或”栏替换所有换行符,而%|
变量扩展中的将删除尾随的栏。
答案2
您可以在 GNU awk 中使用“*段落模式”执行类似的操作:
gawk '
NR==FNR{tbl["CREATE TABLE <SCHEMA_NAME>." $1]; next} ($1 in tbl){ORS=RT; print}
' List_File.txt RS= FS='\n' CREATE_DDLS.txt
CREATE TABLE <SCHEMA_NAME>.ACASE
(
COLUMN1,
COLUMN2,
COLUMN3
) ;
CREATE TABLE <SCHEMA_NAME>.ABC
(
COLUMN1,
COLUMN2,
COLUMN3
) ;
您可以在任何 awk 中执行基本相同的操作,除非您无权访问,RT
因此需要设置ORS
为固定的内容,例如\n\n