Ниже представлен сценарий
У меня есть один файл списка, в котором содержится список имен таблиц, скажем, 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
) ;
Сценарий 1:
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