如何修正Linux sed脚本以生成正确的GRANT语句?
修正Bash脚本生成正确的GRANT语句
问题背景
我有一个名为fks的文件,内容如下:
ALTER TABLE "USER01"."TB01" ADD CONSTRAINT "TB01FK" FOREIGN KEY ("IDUSUARIO") REFERENCES "USER02"."TB02";
需要基于该文件内容生成如下输出:
grant references on "USER02"."TB02" to "USER01";
当前使用的Bash脚本如下:
#!/bin/bash # Read the 'fks' file line by line cat fks | while read line; do # Extract the source schema (after "ALTER TABLE " and before the ".") schema_origin=$(echo $line | sed -E 's/ALTER TABLE "([^"]+)".*/\1/' | tr '[:upper:]' '[:lower:]') # Extract the referenced schema (after "REFERENCES " and before the ".") schema_referenced=$(echo $line | sed -E 's/.*REFERENCES "([^"]+)".*/\1/') # Extract the referenced table name (after the last ".") table_referenced=$(echo $line | sed -E 's/.*\.([^"]+)".*/\1/') # Generate the GRANT statement with the referenced schema and table echo "grant references on \"$schema_referenced\".\"$table_referenced\" to \"$schema_origin\";" done
但输出不正确,结果为:
grant references on "USER02" to "USER01";
问题原因
脚本中提取引用表名的正则表达式错误:使用了HTML转义的引号"匹配实际文件中的双引号",导致无法正确提取表名,最终输出缺失表部分。
修正后的脚本
方案1:修正Sed正则
#!/bin/bash # 逐行读取fks文件 while IFS= read -r line; do # 提取源schema(ALTER TABLE后的第一个引号内容) schema_origin=$(echo "$line" | sed -E 's/ALTER TABLE "([^"]+)".*/\1/' | tr '[:upper:]' '[:lower:]') # 提取被引用的schema(REFERENCES后的第一个引号内容) schema_referenced=$(echo "$line" | sed -E 's/.*REFERENCES "([^"]+)".*/\1/') # 提取被引用的表名(REFERENCES后第二个引号内容) table_referenced=$(echo "$line" | sed -E 's/.*REFERENCES "[^"]+"."([^"]+)".*/\1/') # 生成GRANT语句 echo "grant references on \"$schema_referenced\".\"$table_referenced\" to \"$schema_origin\";" done < fks
方案2:用Awk简化实现(更高效)
#!/bin/bash awk -F'"' '{ schema_origin = tolower($2); schema_referenced = $8; table_referenced = $10; printf "grant references on \"%s\".\"%s\" to \"%s\";\n", schema_referenced, table_referenced, schema_origin; }' fks
关键修正点
- 把正则中的
"替换为实际的双引号",匹配文件中的真实内容。 - 调整表名提取的正则,精准定位到
REFERENCES后的第二个引号内的表名。 - 替换
cat fks | while read line为while IFS= read -r line; do ... done < fks,避免子shell问题,同时保证读取特殊字符和空格的正确性。 - 使用
echo "$line"替代echo $line,防止空格分割内容。
内容的提问来源于stack exchange,提问作者Astora
相关产品推荐
相关产品推荐

