shell管道中的转义SQL参数

shell管道中的转义SQL参数,sql,shell,sed,awk,escaping,Sql,Shell,Sed,Awk,Escaping,我的shell脚本中有这个 ./osmfilter austria-latest.osm --keep="$key=$value" | ./osmconvert - --all-to-nodes --csv="@id @lat @lon @timestamp $key name" --csv-headline | awk -F "\t" '{if($5 != "" && $6 != "") print "INSERT INTO nodes (name, timestamp, la

我的shell脚本中有这个

./osmfilter austria-latest.osm --keep="$key=$value" |
./osmconvert - --all-to-nodes --csv="@id @lat @lon @timestamp $key name" --csv-headline |
awk -F "\t" '{if($5 != "" && $6 != "") print "INSERT INTO nodes (name, timestamp, lat, lon, cid) VALUES (\"",$6,"\",\"",$4,"\",",$2,",",$3,","'$cid'");"}' 
> $value.sql
sed -i '1d' $value.sql
现在,一行输出通常类似于:

INSERT INTO nodes (name, timestamp, lat, lon, cid) VALUES (" OMV "," 2013-06-21T19:46:57Z ", 48.2160931 , 14.2793397 ,2);
但如果名称中有“或”,则SQL导入将失败:

INSERT INTO nodes (name, timestamp, lat, lon, cid) VALUES (" "Landkauf" Bund "," 2014-01-04T10:42:33Z ", 46.7899638 , 15.8526000 ,2);
我可以告诉awk转义所有“内部”,例如$6输出吗?
不必是awk

您可以通过以下方式逃避所有的

awk '{gsub("\"", "\\\"", $6)}
例子 全部 您当前正在使用

awk -F "\t" '{if($5 != "" && $6 != "") print "INSERT INTO nodes (name, timestamp, lat, lon, cid) VALUES (\"",$6,"\",\"",$4,"\",",$2,",",$3,","'$cid'");"}' 
但可以重新格式化为:

awk -F "\t" '$5 && $6 {gsub("\"", "\\\"", $6); printf "INSERT INTO nodes (name, timestamp, lat, lon, cid) VALUES (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\");\n", $6, $4, $2, $3, cid}' cid=$cid
因为:

  • 如果($5!=”&&&$6!=”)
    相当于
    $5&&$6
  • printf
    可以让您更好地控制打印内容
  • $cid
    您不能使用那样的bash变量。您必须使用
    cid
    并使用
    cid=$cid
    作为示例

您可以使用xxd&sed进行此操作。大多数实用程序很难使用引号和斜杠等特殊字符,因此将“a”替换为“a”会导致无法读取的代码。以下命令将您的整个输入转换为十六进制ascii,每行一个十六进制字符。sed然后修改十六进制值,而不必担心特殊字符。Th然后将数据翻译回文本

xxd -ps -c 1 input.txt | sed -e 's/22/5c22/g' -e 's/27/5c27/g' | xxd -r -p
说明:

  • xxd-ps-c1
    将输入文件转换为ascii十六进制代码,每行一个字符
  • 's/22/5c22/g'
    将“转换为”
  • 's/27/5c27/g'
    将“转换为”
  • xxd-r-p
    将十六进制字符还原为文本字符并恢复文件

就像这样?awk-F“\t”{if($5!=”&&&$6!=”)print“插入节点(名称、时间戳、lat、lon、cid)值(\”、gsub(“\”、“\ \”、“\ \”、$6)、“\”、“\”、$4、“、”、“、$2、“、$3、“$cid”);“}“@user638058查看更新的答案并进行进一步解释。+1.xxd,不知道我有这个问题。消除了一整类问题!但这真的解决了OP吗?您是否需要在最后像
|xxd-r-p>input.txt.fix和&mv-f input.txt.fix input.txt那样重定向?
xxd -ps -c 1 input.txt | sed -e 's/22/5c22/g' -e 's/27/5c27/g' | xxd -r -p