使用 awk 修剪 GPS 信息

Trimming GPS information with awk

在一个小 bash 脚本中,我只是尝试 trim GPS 输入数据,以便我在单独的变量中获得经度和纬度值:

  echo $geo_data
  GPS_latitude=$( echo $geo_data | awk -F"+|-" '{print substr([=10=],index([=10=],-1),1) }' )
  GPS_longitude=$( echo $geo_data | awk -F"+|-" '{print substr([=10=],index([=10=],-1),1) }' )
  echo $GPS_latitude
  echo $GPS_longitude

但是我弄出来的好像把每个组件前面的+/-符号搞混了:

-04.7367+055.5230
-04.7367
-055.5230

我以为 index() 参数会完全避免这种情况,但显然我做错了什么。知道如何解决这个问题吗?

您需要从 index 的输出中减去 1 而不是字段值

$ echo '-04.7367+055.5230' | awk -F"+|-" '{print substr([=10=],index([=10=],)-1,1) }' 
-04.7367
$ echo '-04.7367+055.5230' | awk -F"+|-" '{print substr([=10=],index([=10=],)-1,1) }' 
+055.5230


您也可以使用 bash parameter expansion

$ s='-04.7367+055.5230'
$ a="${s%+*}"
$ b="${s#${s%+*}}"
$ echo "$a"
-04.7367
$ echo "$b"
+055.5230

$ # or, use the value of variable 'a'
$ c="${s#$a}"
$ echo "$c"
+055.5230

您可以使用 sed 提取这些值:

geo_data='-04.7367+055.5230'
GPS_latitude=$(sed 's/\(.*\)[-+].*//' <<< "$geo_data")
GPS_longitude=$(sed 's/.*\([-+].*\)//' <<< "$geo_data")
echo "GPS Latitude: ${GPS_latitude} and GPS longitude: ${GPS_longitude}"
# => GPS Latitude: -04.7367 and GPS longitude: +055.5230

online demo

纬度模式是 \(.*\)[-+].*,它将所有字符捕获到最后一个 +- 到第 1 组,然后匹配其余字符。该匹配项将替换为第 1 组内容,因此您将获得最后一个 +- 之前的所有内容。

POSIX BRE 正则表达式详细信息

  • \( - 捕获组 #1 的开始(</code> 从替换模式中引用该值) <ul> <li><code>.* - 任意 0 个或多个字符
  • \) - 捕获组结束
  • [-+] - 匹配 -+
  • 的括号表达式
  • .* - - 任意 0 个或多个字符。
  • GPS_longitude 模式相同,但捕获最后一个 -+ 之后的所有内容,包括加号或连字符。

    使用 bash 和一个正则表达式:

    geo_data="-04.7367+055.5230"
    
    [[ "$geo_data" =~ ^([+-][0-9.]+)([+-][0-9.]+)$ ]]
    echo "${BASH_REMATCH[1]} ${BASH_REMATCH[2]}"
    

    输出:

    -04.7367 +055.5230
    

    grep 解决方案:

    $ geo_data=-04.7367+055.5230
    
    $ echo $geo_data
    -04.7367+055.5230
    
    $ GPS_latitude=$(grep -o '^[+-][^+-]*' <<< $geo_data)
    $ GPS_longitude=$(grep -o '[+-][^+-]*$' <<< $geo_data)
    
    $ echo "GPS Latitude: $GPS_latitude; GPS Longitude: $GPS_longitude"
    GPS Latitude: -04.7367; GPS Longitude: +055.5230