我正在尝试创建一个脚本来查找JSON元素,并使用arg值对其进行更新。
#!/bin/bash
# Shell script to verify the end to end D1 request flow
placeLocation=$1
vehicleHeading=$2
message=$3
file=one.txt
sed -i '' '/location/c\ \"location\" : \"$placeLocation\",' $file
sed -i '' '/heading/c\ \"heading\" : \"$vehicleHeading\",' $file
sed -i '' '/message/c\ \"message\" : \"$message\",' $file
One.txt
"location":"<48.777098,9.181301> - 150.0m",
"message":"Hello there!",
"heading": "34",
但是出现以下错误
sed: 1: "/location/c\ \"locati ...": extra characters after \ at the end of c command
sed: 1: "/heading/c\ \"heading ...": extra characters after \ at the end of c command
sed: 1: "/message/c\ \"message ...": extra characters after \ at the end of c command
sed: 1: "file.txt": invalid command code f
sed: 1: "file.txt": invalid command code f
sed: 1: "file.txt": invalid command code f
sed: 1: "file.txt": invalid command code f
我刚刚开始学习sed编辑器,并尝试了多种方法,但无法弄清楚。任何帮助深表感谢!
答案 0 :(得分:1)
请注意,您可能应该考虑使用jq
之类的工具来编辑JSON文件。但是我认为您有充分的理由使用sed
,所以那里有两个问题。
首先,您要在Mac OS X版本的sed上使用不具有这些功能的GNU sed功能。如果要在Mac OS X上使用GNU sed,请安装它:
▶ brew install gnu-sed
为GNU sed(以及其他有关引用字符串的Bash样式指南建议)修复代码:
cat > FILE <<EOF
"location":"<48.777098,9.181301> - 150.0m",
"message":"Hello there!",
"heading": "34",
EOF
placeLocation=myPlaceLocation
vehicleHeading=myVehicleHeading
message=myMessage
file=FILE
gsed -i -e '/location/c\' -e '"location": "'"$placeLocation"'",' "$file"
gsed -i -e '/heading/c\' -e '"heading": "'"$vehicleHeading"'",' "$file"
gsed -i -e '/message/c\' -e '"message": "'"$message"'",' "$file"
如GNU sed manual中所述,与-e
命令在同一行上使用多个c\
命令是GNU扩展。
如果要使用Mac OS X的sed,也许可以用这种方式编写:
sed -i '' '
s/"location".*/"location": "'"$placeLocation"'",/
s/"heading".*/"heading": "'"$vehicleHeading"'",/
s/"message".*/"message": "'"$message"'",/
' "$file"
但是请注意,如果您需要代码对所有输入都具有鲁棒性,则必须清理输入。
答案 1 :(得分:1)
要可靠地执行此操作,您需要使用能够理解文字字符串(sed不能理解-参见Is it possible to escape regex metacharacters reliably with sed)的工具,例如awk:
$ awk 'BEGIN{FS=OFS=":"; val=ARGV[1]; ARGV[1]=""} $1=="\"message\""{sub(FS".*",FS); print $1, "\""val"\""}' 'what is 1/2?' one.txt
"message":"what is 1/2?"
$ awk 'BEGIN{FS=OFS=":"; val=ARGV[1]; ARGV[1]=""} $1=="\"message\""{sub(FS".*",FS); print $1, "\""val"\""}' 'what is 1&2?' one.txt
"message":"what is 1&2?"
$ awk 'BEGIN{FS=OFS=":"; val=ARGV[1]; ARGV[1]=""} $1=="\"message\""{sub(FS".*",FS); print $1, "\""val"\""}' 'what is \1?' one.txt
"message":"what is \1?"
以上内容将在每个UNIX盒上的任何shell中使用任何awk来可靠地运行。尝试在sed命令中将它们用作替换字符串。
执行所需操作的完整脚本将是:
#!/bin/env bash
# Shell script to verify the end to end D1 request flow
placeLocation=$1
vehicleHeading=$2
message=$3
file=one.txt
tmp=$(mktemp)
awk '
BEGIN {
split("location heading message", tags)
for (i in tags) {
vals["\"" tags[i] "\""] = "\"" ARGV[i] "\""
ARGV[i] = ""
}
FS=OFS=":"
}
$1 in vals {
tag = $1
sub(FS".*","")
$0 = tag OFS vals[tag]
}
1' "$placeLocation" "$vehicleHeading" "$message" "$file" > "$tmp" && mv "$tmp" "$file"