Unten ist das Szenario
Ich habe eine Listendatei mit Tabellennamen von, sagen wir, 10 Tabellen und eine weitere Datei mit allen erstellten DDLs, etwa 100.
Ich muss DDLS aus der zweiten Datei für die Tabellen extrahieren, die in der ersten Datei vorhanden sind. Ich habe dies mithilfe des sed
Befehls erreicht. Allerdings trat bei mir das Problem auf, dass mein Befehl für einige Tabellen und einige zusätzliche Tabellen, die nicht in der ersten Datei enthalten sind, zweimal kopiert wurde.
Zum Beispiel:
mein List_File.txt
hat
ACASE
ABC
ABCH
CREATE_DDLS.txt
hat
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
) ;
Szenario 1:
ACASE ist in der Listendatei vorhanden und in der zweiten Datei befinden sich ACASE/ACASE01/ACASE03. Der folgende Befehl kopiert alle drei Tabellen, wobei ich nur ACASE brauche, um DDL für die Ausgabe zu erstellen.
Szenario 2:
ABC und ABCD sind in der Listendatei vorhanden, der Befehl gibt die ABCD-Tabelle zweimal aus, obwohl ich nur ein ABCD benötige.
Unten ist der Befehl, den ich ausführe
while read -r line
do
sed -n '/CREATE TABLE SCHEMANAME.TABLENAME/,/\;/p' Create DDLS file
done < List file > NewFile.txt
Jede Hilfe wird sehr geschätzt.
Danke
Antwort1
Ihr Beispiel und/oder Versuch ist falsch.
Wie dem auch sei, wenn ich Ihre Beispieldatei nehme, könnte Ihr Skript wahrscheinlich
while read -r line; do
sed -n "/CREATE TABLE <SCHEMA_NAME>.$line/,/;/p" CREATE_DDLs.txt ;
done < List_File.txt
und es wird mit allen Datensätzen übereinstimmen, weil ACASE
auch übereinstimmt . Als Anker für das Zeilenende ACASE01
verwenden :$
while read -r line; do
sed -n "/CREATE TABLE <SCHEMA_NAME>.$line$/,/;/p" CREATE_DDLs.txt ;
done < List_File.txt
Das heißt, bei einer längeren Liste von Tabellen ist es nicht sehr effizient, die ganze Datei immer wieder zu durchsuchen, während Sie mit erweiterten regulären Ausdrücken nach etwas wie suchen können (ACASE|ABC|ABCH)
. Bringen Sie also die erste Datei in die richtige Form und verwenden Sie sie im Suchmuster:
TABLES=$(cat List_File.txt|tr '\n' '|')
sed -nE "/CREATE TABLE <SCHEMA_NAME>.(${TABLES%|})$/,/;/p" CREATE_DDLs.txt
Dadurch tr
werden alle Zeilenumbrüche durch ODER-Striche ersetzt, während %|
in der Variablenerweiterung der abschließende Strich entfernt wird.
Antwort2
Mit dem „Absatzmodus“ in GNU awk könnten Sie etwa Folgendes erreichen:
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
) ;
Sie können im Wesentlichen dasselbe in jedem Awk tun, außer dass Sie keinen Zugriff darauf haben und RT
daher etwas Festes festlegen müssen, ORS
wie\n\n