如何从 gdalinfo 输出中提取特定信息?

Posted

技术标签:

【中文标题】如何从 gdalinfo 输出中提取特定信息?【英文标题】:How to extract specific information from gdalinfo output? 【发布时间】:2017-07-19 11:43:27 【问题描述】:

我正在使用 GDAL 获取有关卫星图像的信息。 stdout 如下所示:

$ gdalinfo B02.jp2
Driver: JPEG2000/JPEG-2000 part 1 (ISO/IEC 15444-1)
Files: B02.jp2
       B02.jp2.aux.xml
Size is 10980, 10980
Coordinate System is:
PROJCS["WGS 84 / UTM zone 15N",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AXIS["Latitude",NORTH],
        AXIS["Longitude",EAST],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-93],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH],
    AUTHORITY["EPSG","32615"]]
Origin = (600000.000000000000000,5400000.000000000000000)
Pixel Size = (10.000000000000000,-10.000000000000000)
...

当我尝试从stdout 中提取一行时,会产生错误:

$ gdalinfo B02.jp2 | grep Origin
maximum number of samples exceeded (120560400 > 67108864)
error: cannot decode code stream
Origin = (600000.000000000000000,5400000.000000000000000)

如何从输出中提取信息(例如Origin)并将其分配给变量?

【问题讨论】:

你只需要600000.000000000000000,5400000.000000000000000或完整的字符串Origin = (600000.000000000000000,5400000.000000000000000) 理想情况下,我想做类似some_variable = "600000.000000000000000,5400000.000000000000000" 【参考方案1】:

您可以使用GNU grepPCRE 标志启用的PCRE 功能,并仅在braces() 中存储匹配的单词

gdalinfo B02.jp2 2>/dev/null | grep -oP 'Origin = \(\K[^\)]+'
600000.000000000000000,5400000.000000000000000

2>/dev/null 用于抑制命令中的错误消息。要将其存储在变量中,只需这样做,

myOriginInfo="$(gdalinfo B02.jp2 2>/dev/null | grep -oP 'Origin = \(\K[^\)]+')"
printf "%s\n" "$myOriginInfo"

由于您没有安装GNU grep,您可以使用此POSIX 兼容awk 表达式来实现您的结果,

awk 'BEGINFS="[()]"/Origin/print $2' file
600000.000000000000000,5400000.000000000000000

and) 在变量中

myOriginInfo="$(gdalinfo B02.jp2 2>/dev/null | awk 'BEGINFS="[()]"/Origin/print $2')"

【讨论】:

这会产生以下输出:usage: grep [-abcDEFGHh....。似乎没有将文本分配给 myOriginInfo 变量。 @Borealis:你好像没有安装GNU grep,你能检查grep --version的输出吗? 产生:grep (BSD grep) 2.5.1-FreeBSD @Borealis:啊,错过了GNU tools,你可以安装GNU grep吗?你在Mac OS X吗? fwiw,macOS(以及 FreeBSD)用户可以选择从 MacPorts 或 HomeBrew 安装 pcregrep。它是pcre 包的一部分。【参考方案2】:

如果愿意,您可以使用 bash 参数扩展将输出缩减为您感兴趣的数据。

$ x=$(gdalinfo B02.jp2 2>/dev/null | grep ^Origin)
$ x="$x#*("; x="$x%)"
$ printf '%s\n' "$x"
600000.000000000000000,5400000.000000000000000

另一个有趣的选择是完全避免使用grep,并尝试将程序输出解释为字段:

declare -A a       # declare an associative array (requires bash 4)

while IFS="=" read -r key value; do
  [[ -n "$value" ]] && a[$key% ]="$value# "
done < <(gdalinfo B02.jp2 2>/dev/null)

结果将是一个数组a[],您可以使用它执行以下操作:

$ printf '%s\n' "$a[Origin]"
(600000.000000000000000,5400000.000000000000000)

如果你愿意,当然可以使用参数扩展去掉括号。

$ printf '%s\n' "$a[Origin]:1:$(($#a[Origin]-2))"
600000.000000000000000,5400000.000000000000000

请注意,macOS 默认安装了 bash 版本 3;如果你想使用 bash 4,你可以使用 MacPorts 或 HomeBrew 安装它。

【讨论】:

以上是关于如何从 gdalinfo 输出中提取特定信息?的主要内容,如果未能解决你的问题,请参考以下文章

如何从角度输出中提取信息

如何使用gdalinfo.exe获得hdf文件的子数据集

Python帮助-如何从一维数组中提取特定范围的值? [重复]

如何从 C++ 中的 getline 函数中提取特定的子字符串?

python 从文本中提取每一行的特定字符串输出到csv文件

如何在 SQL 中提取特定的多个文本?