如何正确使用正则表达式从 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/ 上使用该命令输出和模式对其进行了测试。
匹配于
http://if-build-d9.lndo.site
(这是我唯一关心的比赛)
http://if-build-d9-redis-primary.lndo.site
http://if-build-d9-mail.lndo.site
看来我在 Bash 中对正则表达式的使用不正确。
Bash 使用 POSIX ERE 正则表达式风格,[\w\S]
匹配 \
、w
或 S
而不是任何字符,而是空格如你所料。
您似乎只想 grep -o
ut 具有特定模式的 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,结果更好。
我有一个命令 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/ 上使用该命令输出和模式对其进行了测试。
匹配于
http://if-build-d9.lndo.site
(这是我唯一关心的比赛)http://if-build-d9-redis-primary.lndo.site
http://if-build-d9-mail.lndo.site
看来我在 Bash 中对正则表达式的使用不正确。
Bash 使用 POSIX ERE 正则表达式风格,[\w\S]
匹配 \
、w
或 S
而不是任何字符,而是空格如你所料。
您似乎只想 grep -o
ut 具有特定模式的 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,结果更好。