【问题标题】:Capture group from regex in bash script从 bash 脚本中的正则表达式捕获组
【发布时间】:2019-08-06 12:45:05
【问题描述】:

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

在下面的模拟脚本中,我显示了构建命令的输出。需要截取的部分是以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。

【问题讨论】:

标签: regex bash macos centos


【解决方案1】:

有很多方法,这是一种:

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

【讨论】:

    【解决方案2】:

    在 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)来匹配所有可能性(并调整用于BASH_REMATCH 的索引)。

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

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

    关于正则表达式:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 2011-11-01
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      相关资源
      最近更新 更多