如何使用 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
。您可以重复使用的部分是1
和2
. - 所以在
if
中,每个数字都用括号括起来。 - 当
=~
被处理时,BASH_REMATCH
数组被定义为每个部分。 - 可以删除或注释掉“DEBUG”
echo
语句。
如果您在 KML 文件中有多个“Extent: ...”,您可以循环处理每一行。