使用 sed 处理 bash 变量

con*_*fin 19 shell scripting bash sed shell-script

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

Jan*_*der 26

SiegeX 的答案对于这种特殊情况更好,但您还应该知道如何将任意文本传递给sed.

sed期望文件名作为其第二、第三等参数,如果找不到任何文件名,则从其标准输入中读取。因此,如果您要处理不在文件中的文本,则必须将其通过管道传输到sed. 最直接的方法是这样的:

echo "blah blah" | sed 's/blah/blam/g'
Run Code Online (Sandbox Code Playgroud)

所以你的例子会变成:

LAT=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\1/g')
LON=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\2/g')
Run Code Online (Sandbox Code Playgroud)

替代(更好但更模糊)方法

如果您认为有$LATLNG可能以破折号开头,或者如果您想学究,您应该使用printf代替echo

printf '%s' "$LATLNG" | sed 's/foo/bar/g'
Run Code Online (Sandbox Code Playgroud)

或“此处的文档”,但这对于您正在使用的构造可能有点尴尬:

LAT=$(sed 's/foo/bar/g' <<END
$LATLNG
END
)
Run Code Online (Sandbox Code Playgroud)

或者,如果您正在使用bash并且不担心便携性,则可以使用“此处字符串”:

sed 's/foo/bar/g' <<< "$LATLNG"
Run Code Online (Sandbox Code Playgroud)


Sie*_*geX 18

这可以通过纯 shell 语法解决。由于括号(括号),它确实需要一个临时变量:

#!/bin/bash

LATLNG="(53.3096,-6.28396)"

tmp=${LATLNG//[()]/}
LAT=${tmp%,*}
LNG=${tmp#*,}
Run Code Online (Sandbox Code Playgroud)

或者,您可以通过使用IFS和使用read内置函数一次性完成:

#!/bin/bash

LATLNG="(53.3096,-6.28396)"

IFS='( ,)' read _ LAT LNG _ <<<"$LATLNG"
Run Code Online (Sandbox Code Playgroud)