UNIX - Замена переменных в sql с соответствующими значениями из файла.profile

81
5

Я пытаюсь написать оболочку, которая будет принимать файл SQL в качестве входных данных. Пример файла SQL:

SELECT *
FROM %%DB.TBL_%%TBLEXT
WHERE CITY = '%%CITY'

Теперь скрипт должен извлечь все переменные, которые в этом случае будут все, начиная с %%. Таким образом, выходной файл будет выглядеть следующим образом:

%%DB
%%TBLEXT
%%CITY

Теперь я должен иметь возможность извлекать соответствующие значения из файла.profile для этих переменных и создавать SQL файл с соответствующими значениями.

SELECT *
FROM tempdb.TBL_abc
WHERE CITY = 'Chicago'

На данный момент я пытаюсь сгенерировать файл1, который будет содержать все переменные. Ниже образец кода -

sed "s/[(),']//g" "T:/work/shell/sqlfile1.sql" | awk '/%%/{print $NF}' | awk '/%%/{print $NF}' > sqltemp2.sql

берет меня до

%%DB.TBL_%%TBLEXT
%%CITY

Может ли кто-нибудь помочь мне получить файл1, перечисляя переменные?

спросил(а) 2015-05-25T09:09:00+03:00 5 лет, 5 месяцев назад
1
Решение
81

Вы можете использовать grep и sort для получения списка уникальных переменных в соответствии со следующей стенограммой:

$ echo "SELECT *
FROM %%DB.TBL_%%TBLEXT
WHERE CITY = '%%CITY'" | grep -o '%%[A-Za-z0-9_]*' | sort -u
%%CITY
%%DB
%%TBLEXT

Флаг -o grep дает указание только распечатать соответствующие части строк, а не всю строку, а также выводит каждую соответствующую часть на отдельной строке. Затем sort -u просто убедится, что дубликатов нет.

Что касается полного процесса, здесь небольшая модификация сценария bash который я использовал для аналогичных целей:

# Define all translations.

declare -A xlat
xlat['%%DB']='tempdb'
xlat['%%TBLEXT']='abc'
xlat['%%CITY']='Chicago'

# Check all variables in input file.

okay=1
for key in $(grep -o '%%[A-Za-z0-9_]*' input.sql | sort -u) ; do
if [[ "${xlat[$key]}" == "" ]] ; then
echo "Bad key ($key) in file:"
grep -n "${key}" input.sql | sed 's/^/ /'
okay=0
fi
done
if [[ ${okay} -eq 0 ]] ; then
exit 1
fi

# Process input file doing substitutions. Fairly
# primitive use of sed, must change to use sed -i
# at some point.
# Note we sort keys based on descending length so we
# correctly handle extensions like "NAME" and "NAMESPACE",
# doing the longer ones first makes it work properly.

cp input.sql output.sql
for key in $( (
for key in ${!xlat[@]} ; do
echo ${key}
done
) | awk '{print length($0)":"$0}' | sort -rnu | cut -d':' -f2) ; do
sed "s/${key}/${xlat[$key]}/g" output.sql >output2.sql
mv output2.sql output.sql
done

cat output.sql

Сначала он проверяет, что входной файл не содержит ключей, не найденных в массиве переводов. Затем он применяет sed замены к входному файлу, по одному на перевод, чтобы все ключи были заменены соответствующими значениями.

Это должно быть хорошим началом, хотя могут быть некоторые крайние случаи, такие, как если ключи или значения содержат символы sed будет считать важными (например, / например). Если это так, вам, вероятно, нужно будет избежать их, например, изменить:

xlat['%%UNDEFINED']='0/0'

в:

xlat['%%UNDEFINED']='0\/0'

ответил(а) 2015-05-25T09:20:00+03:00 5 лет, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема