bash 变量 LATLNG 在括号中包含纬度和经度值,如下所示
(53.3096,-6.28396)
我想将它们解析为一个名为 LAT 和 LON 的变量,我试图通过 sed 这样做
LAT=$(sed "s/(\(.*\),\(.*\))/\1/g" "$LATLNG")
LON=$(sed "s/(\(.*\),\(.*\))/\2/g" "$LATLNG")
但是,我收到以下错误:
sed: can't read (53.3096,-6.28396): No such file or directory
答案1
SiegeX 的答案更适合这种特殊情况,但您还应该知道如何将任意文本传递到sed
.
sed
期望文件名作为其第二个、第三个等参数,如果没有找到任何文件名,它将从标准输入中读取。因此,如果您想要处理的文本不在文件中,则必须将其通过管道传输到sed
.最直接的方法是这样的:
echo "blah blah" | sed 's/blah/blam/g'
所以你的例子将变成:
LAT=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\1/g')
LON=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\2/g')
替代(更好但更晦涩)方法
如果你认为有可能以$LATLNG
破折号开头,或者如果你想学究气,你应该使用printf
而不是echo
:
printf '%s' "$LATLNG" | sed 's/foo/bar/g'
或者“此处文档”,但这对于您正在使用的结构来说可能有点尴尬:
LAT=$(sed 's/foo/bar/g' <<END
$LATLNG
END
)
或者,如果您正在使用bash
并且不担心可移植性,则可以使用“此处字符串”:
sed 's/foo/bar/g' <<< "$LATLNG"
答案2
这可以通过纯 shell 语法来解决。但由于括号(方括号),它确实需要一个临时变量:
#!/bin/bash
LATLNG="(53.3096,-6.28396)"
tmp=${LATLNG//[()]/}
LAT=${tmp%,*}
LNG=${tmp#*,}
IFS
或者,您可以通过使用内置函数一次性完成此操作read
:
#!/bin/bash
LATLNG="(53.3096,-6.28396)"
IFS='( ,)' read _ LAT LNG _ <<<"$LATLNG"
答案3
这是一个适用于任何 POSIX shell 的解决方案:
parse_coordinates () {
IFS='(), ' # Use these characters as word separators
set -f # Disable globbing
set $1 # Split $1 into separate words
set +f # Restore shell state
unset IFS
LAT=$2 # $1 is the empty word before the open parenthesis
LON=$3
}
parse_coordinates "$LATLNG"
这是另一个同样可移植的解决方案,它解析所使用的特定语法。
LAT=${LATLNG%\)} # strip final parenthesis
LAT=${LAT#\(} # strip initial parenthesis
LON=${LAT##*[, ]} # set LON to everything after the last comma or space
LAT=${LAT%%[, ]*} # set LAT to everything before the first comma or space
答案4
LATLNG="(53.3096,-6.28396)"
set ${LATLNG//[(,)]/ }
LAT=$1
LON=$2