如何使用 shell 脚本获取管道命令的正则表达式匹配项?

How do I obtain regex matches of piped command using shell script?

首先,我试图从 KML 文件中获取某个 属性。现在,我尝试了

ogrinfo C:/test.kml -so -al | findstr "Extent"

向我推荐并输出

Extent: (-100.054053, 33.702234) - (-94.647180, 37.125712)

我需要这个表格

-100.054053,-94.647180,33.702234,37.125712 我想使用正则表达式。

我尝试了以下方法只是为了看看它输出了什么:

ogrinfo C:/test.kml -so -al | findstr "Extent" | findstr /r /c:"-*[0-9]*\.[0-9]*"

但这仍然输出

Extent: (-100.054053, 33.702234) - (-94.647180, 37.125712)

我在某处读到 Windows' FINDSTR 只输出匹配的行,而不是正则表达式匹配本身。还有其他方法吗?

如果我成功了,我会在 shell 脚本中以某种方式将匹配项保存在不同的变量中。我不是 shell 脚本编写方面的专家,但我一直在四处寻找并正在考虑做这样的事情

#!/bin/bash

for /f "tokens=*" %%a in ('ogrinfo C:/test.kml -so -al ^| findstr "Extent" ^| findstr /r /c:"-*[0-9]*\.[0-9]*"') do (
  echo %%a
  #do something
)
done >output

但是 运行 这会导致 shell 立即消失,甚至看不到错误。

假设

  • 您有一个包含原始数据的 kml 文件。

  • 您可以提取以“Extent:”开头的单行以获得您想要的值

  • 单行 => kml 文件中只有 1 行采用该格式

  • 该行的格式为:

    Extent: (NUMBER1, NUMBER2) - (NUMBER3, NUMBER4)
    
  • 一个数字可以有以下字符:0 1 2 3 4 5 6 7 8 9 . -

  • 你想要的输出是:

    NUMBER1,NUMBER3,NUMBER2,NUMBER4
    

仅使用 Linux 工具,您可以这样做:

#!/bin/bash
#
datafile="data.kml"

# Ensure the data file exists
if [[ ! -f "$datafile" ]]
then
    echo "ERROR: the data file does not exist."
    exit 1
fi

# Extract the "Extent:" line
dataline=$(grep "Extent: " "$datafile")

# Make sure the line is of a valid format, and assign the number variables
if [[ $dataline =~ "Extent: ("([0-9.-]+)", "([0-9.-]+)") - ("([0-9.-]+)", "([0-9.-]+)")" ]] && number1="${BASH_REMATCH[1]}" && number2="${BASH_REMATCH[2]}" && number3="${BASH_REMATCH[3]}" && number4="${BASH_REMATCH[4]}"
then
    echo "-----DEBUG-----"
    echo "line==$dataline"
    echo "1==$number1"
    echo "2==$number2"
    echo "3==$number3"
    echo "4==$number4"
    echo "-- END DEBUG --"
    echo ""
    echo "$number1,$number3,$number2,$number4"
else
    echo "ERROR: there is no \"Extent: \" line in the data file ($datafile)"
fi

详情:

  • 一切都在 if 行中完成。
  • =~ 将左侧与右侧的模式匹配。
  • 在正则表达式中,您可以使用 ( ) 定义要重用的部分。
  • 例如:abcd(1)efgh(2)ijkl。您可以重复使用的部分是 12.
  • 所以在if中,每个数字都用括号括起来。
  • =~ 被处理时,BASH_REMATCH 数组被定义为每个部分。
  • 可以删除或注释掉“DEBUG”echo 语句。

如果您在 KML 文件中有多个“Extent: ...”,您可以循环处理每一行。