在bash脚本中从正则表达式捕获组

时间:2019-03-15 12:25:07

标签: regex bash macos centos

构建R软件包时,该命令将处理步骤输出到std out。从该输出中,我想捕获包的最终名称。

在下面的模拟脚本中,我显示了build命令的输出。需要捕获的部分是从building开始的最后一行。

如何获取与这些引号匹配的正则表达式,然后将包名称捕获到变量中?

#!/usr/bin/env bash

var=$(cat <<"EOF"
Warning message:
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘analysis’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
Removed empty directory ‘analysis/.idea/inspectionProfiles’
Removed empty directory ‘analysis/.idea/snapshots’
* creating default NAMESPACE file
* building ‘analysis_0.1.tar.gz’
EOF
)

regex="building [\u2018](.*?)?[\u2019]"

if [[ "${var}" =~ $regex ]]; then
  pkgname="${BASH_REMATCH[1]}"
  echo "${pkgname}"
else
  echo "sad face"
fi

这在macOS和CentOS上都应该起作用。

2 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点,

file=`echo "$var" | grep '^\* building' | grep -o '‘.*’' | head -c -4 | tail -c +4`
echo $file
  • 找到以* building(第一个grep)开头的行
  • ‘’(第二个grep)之间查找文本
  • 舍弃引号(前4个字节和后4个字节)(头部和尾部)

答案 1 :(得分:1)

在Bash 4.2中引入了对\u\U Unicode转义的支持。 CentOS 7具有Bash 4.2,因此可以在该平台上运行:

regex=$'.*building[[:space:]]+\u2018(.*)\u2019'

不幸的是,早期版本的CentOS具有较旧的Bash版本,我相信MacOS上Bash的默认版本仍为3.2。对于这些,假设引号编码为UTF-8,这应该可以工作:

regex=$'.*building[[:space:]]+\xe2\x80\x98(.*)\xe2\x80\x99'

如果引号在不同的平台上以不同的方式编码,则可以使用交替(例如,用(\xe2\x80\x98|...)代替xe2\x80\x98)来匹配所有可能性(并调整用于{{ 1}})。

有关Bash中Unicode的更多信息,请参见How do you echo a 4-digit Unicode character in Bash?

我使用BASH_REMATCH来设置正则表达式,因为它支持$'...'并且(从Bash 4.2起)支持\x转义字符,而Bash不支持正则表达式。

关于正则表达式: