以下はシナリオです
1 つのリスト ファイルがあり、その中にはテーブル名 (たとえば 10 個のテーブル) のリスト ファイルがあり、別のファイルには約 100 個のすべての作成 DDL が含まれています。
最初のファイルに存在するテーブルに対して、2 番目のファイルから DDLS を抽出して作成する必要があります。sed
コマンドを使用してこれを達成しました。ただし、コマンドがいくつかのテーブルを 2 回コピーし、最初のファイルにないいくつかの余分なテーブルもコピーするという問題が発生しました。
例えば;
私の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
) ;
シナリオ 1:
リスト ファイルに ACASE が存在し、2 番目のファイルに ACASE/ACASE01/ACASE03 がある場合、以下のコマンドは、ACASE 作成 DDL のみを必要とする 3 つのテーブルすべてを出力にコピーします。
シナリオ2:
リスト ファイルには ABC と ABCD が存在しますが、必要なのは ABCD が 1 つだけなのに、コマンドは ABCD テーブルを 2 回出力しています。
以下は私が実行しているコマンドです
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