我正在尝试编写一个将SQL文件作为输入的shell。示例SQL文件:
SELECT *
FROM %%DB.TBL_%%TBLEXT
WHERE CITY = '%%CITY'
现在脚本应该提取所有变量,在这种情况下,所有变量都以%%开头。所以输出文件将如下所示:
%%DB
%%TBLEXT
%%CITY
现在,我应该能够从用户的.profile文件中提取这些变量的匹配值,并使用正确的值创建SQL文件。
SELECT *
FROM tempdb.TBL_abc
WHERE CITY = 'Chicago'
截至目前,我正在尝试生成包含所有变量的file1。代码示例 -
sed "s/[(),']//g" "T:/work/shell/sqlfile1.sql" | awk '/%%/{print $NF}' | awk '/%%/{print $NF}' > sqltemp2.sql
带我到
%%DB.TBL_%%TBLEXT
%%CITY
有人可以帮我找到列出变量的file1吗?
答案 0 :(得分:0)
您可以使用grep
和sort
获取唯一变量列表,具体如下:
$ echo "SELECT *
FROM %%DB.TBL_%%TBLEXT
WHERE CITY = '%%CITY'" | grep -o '%%[A-Za-z0-9_]*' | sort -u
%%CITY
%%DB
%%TBLEXT
-o
的{{1}}标志指示它仅打印行的匹配部分而不是整行,并且还输出 distinct 行上的每个匹配部分。然后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'