Bash

使用 sed 處理 bash 變數

  • March 18, 2019

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

這可以通過純 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"

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"

引用自:https://unix.stackexchange.com/questions/6629