下面是場景
我有一個列表文件,其中有包含表名的列表文件(假設有 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
以 OR 條取代所有換行符,而%|
變數擴充中的 將會刪除尾隨條。
答案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