如何正确使用正则表达式从 Bash 中的命令输出中进行搜索?

How to properly use regex to search from a command's output in Bash?

我有一个命令 lando info,它有一个相当大的多行输出:

[ { service: 'appserver',
    urls:
     [ 'https://localhost:52836',
       'http://localhost:52837',
       'http://if-build-d9.lndo.site/',
       'https://if-build-d9.lndo.site/' ],
    type: 'php',
    healthy: true,
    via: 'apache',
    webroot: './web',
    config: { php: '/Users/runo/.lando/config/drupal9/php.ini' },
    version: '7.3',
    meUser: 'www-data',
    hasCerts: true,
    hostnames: [ 'appserver.ifbuildd9.internal' ] },
  { service: 'database',
    urls: [],
    type: 'mysql',
    healthy: true,
    internal_connection: { host: 'database', port: '3306' },
    external_connection: { host: '127.0.0.1', port: '52835' },
    healthcheck: 'bash -c "[ -f /bitnami/mysql/.mysql_initialized ]"',
    creds: { database: 'drupal9', password: 'drupal9', user: 'drupal9' },
    config: { database: '/Users/runo/.lando/config/drupal9/mysql.cnf' },
    version: '5.7',
    meUser: 'www-data',
    hasCerts: false,
    hostnames: [ 'database.ifbuildd9.internal' ] },
  { service: 'redis_primary',
    urls: [ 'http://if-build-d9-redis-primary.lndo.site/' ],
    type: 'redis',
    healthy: true,
    internal_connection: { host: 'redis_primary', port: '6379' },
    external_connection: { host: '127.0.0.1', port: '52838' },
    config: {},
    version: '6',
    meUser: 'www-data',
    hasCerts: false,
    hostnames: [ 'redis_primary.ifbuildd9.internal' ] },
  { service: 'mailhog',
    urls: [ 'http://localhost:52840', 'http://if-build-d9-mail.lndo.site/' ],
    type: 'mailhog',
    healthy: true,
    hogfrom: [ 'appserver' ],
    internal_connection: { host: 'mailhog', port: '1025' },
    external_connection: { host: '127.0.0.1', port: '52839' },
    config: {},
    version: 'v1.0.0',
    meUser: 'mailhog',
    hasCerts: false,
    hostnames: [ 'mailhog.ifbuildd9.internal' ] } ]

我想在 bash 变量中捕获值 http://if-build-d9.lndo.site

我有这个 shell 脚本,但是它 returns 空值:

 lando_info=$(lando info); 
 regex_pattern='/http:\/\/[\w\S]*.lndo.site/g'; 
 [[ "$lando_info" =~ $regex_pattern ]]; 
 echo "${BASH_REMATCH[0]}"
 echo "${BASH_REMATCH[1]}"
 echo "${BASH_REMATCH[2]}"

这会输出空字符串。

我知道正则表达式本身应该是有效的,因为我在 https://www.regexpal.com/ 上使用该命令输出和模式对其进行了测试。

匹配于

看来我在 Bash 中对正则表达式的使用不正确。

Bash 使用 POSIX ERE 正则表达式风格,[\w\S] 匹配 \wS 而不是任何字符,而是空格如你所料。

您似乎只想 grep -out 具有特定模式的 URL,因此请使用

grep -oE 'http://[^[:space:]]*\.lndo\.site' <<< "$lando_info"

online demo。输出:

http://if-build-d9.lndo.site
http://if-build-d9-redis-primary.lndo.site
http://if-build-d9-mail.lndo.site

[^[:space:]]* 是一个否定括号表达式,它包含一个 POSIX 字符 class 并匹配除空白字符之外的任何零个或多个字符。 -o 选项允许 grep 只提取匹配项,而不是匹配行。

我最终使用了 jq,结果更好。