sed または awk コマンドを使用して、中程度に複雑なシナリオを実現するのを手伝ってくれる人はいませんか?

sed または awk コマンドを使用して、中程度に複雑なシナリオを実現するのを手伝ってくれる人はいませんか?

以下はシナリオです

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

関連情報