Bash 使用正则表达式同时进行 Grep 和排除
Bash to Grep and Exclude At the Same Time Using Regex
我想从命令输出中 grep 一个字符串,但同时删除一个子字符串。例如
String = 活动:活动 (运行) 自星期六 2022-03-12 20:02:20 PKT; 1 小时 31 分钟前
我想要的 = 活动 (运行) 自 20:02:20 PKT
已删除
- 活跃:
- 2022-03-12 星期六
- ; 1 小时 31 分钟前
为此,我最初一直在使用正则表达式
sudo service sshd status |grep -Po '(?<=Active: )(.*) since (.*);'
active (running) since Mon 2022-03-14 01:06:43 PKT;
你能告诉我如何忽略日期和最后一个分号吗?同时只保留时间并输出完全一样:
active (running) since 01:06:43 PKT
谢谢
命令的完整输出:
● xrdp.service - xrdp daemon
Loaded: loaded (/lib/systemd/system/xrdp.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-03-14 01:06:44 PKT; 3 days ago
Docs: man:xrdp(8)
man:xrdp.ini(5)
Process: 668 ExecStartPre=/bin/sh /usr/share/xrdp/socksetup (code=exited, status=0/SUCCESS)
Process: 682 ExecStart=/usr/sbin/xrdp $XRDP_OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 687 (xrdp)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/xrdp.service
└─687 /usr/sbin/xrdp
systemd[1]: Starting xrdp daemon...
xrdp[682]: (682)(-1224841088)[DEBUG] Testing if xrdp can listen on 0.0.0.0 port 3389.
xrdp[682]: (682)(-1224841088)[DEBUG] Closed socket 7 (AF_INET6 :: port 3389)
systemd[1]: xrdp.service: Can't open PID file /run/xrdp/xrdp.pid (yet?) after start: No such file or directory```
你可以使用
sed -nE 's/^ *Active: +(.* since ).*([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*).*//p'
详情:
-nE
- n
抑制默认行输出并且 E
启用 POSIX ERE 正则表达式语法
^Active: +(.* since ).*([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*).*
- 查找匹配的行
^ *Active: +
- 字符串的开头,零个或多个 spaces,Active:
和一个或多个 spaces
(.* since )
- 第 1 组 (</code>):任意文本,然后是 space + <code>since
+ space
.*
- 任何文本
([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*)
- 两位数,:
,两位数,:
,两位数,然后是 ;
[=53= 以外的任何零个或多个字符]
.*
- 字符串的其余部分
</code> - 连接第 1 组和第 2 组值</li>
<li><code>p
- p
打印替换结果。
#!/bin/bash
s=' Active: active (running) since Sat 2022-03-12 20:02:20 PKT; 1h 31min ago'
sed -nE 's/^ *Active: +(.* since ).*([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*).*//p' <<< "$s"
输出:
active (running) since 20:02:20 PKT
使用您显示的示例,请尝试以下 awk
代码。用 GNU awk
编写和测试。简单的解释是,创建一个名为 val
的 shell 变量并将其值发送到 awk
然后在 awk
程序中我使用 match
函数将正则表达式匹配到获取所需的值。
val="Active: active (running) since Sat 2022-03-12 20:02:20 PKT; 1h 31min ago"
echo "$val" |
awk '
match([=10=],/^Active:[[:space:]]+active \(running\)[[:space:]]+.*[0-9]{4}(-[0-9]{2}){2}[[:space:]]+([0-9]{2}:){2}[0-9]{2}[^;]*/){
val=substr([=10=],RSTART,RLENGTH)
sub(/^Active:[[:space:]]+/,"",val)
sub(/since[[:space:]]+\S+\s+\S+/,"since",val)
print val
}
'
正则表达式解释:
^Active:[[:space:]]+ ##Matching value starting from Active: followed by space(s).
active \(running\) ##matching active followed by a space followed by (running).
[[:space:]]+.*[0-9]{4} ##Matching 1 or more spaces then using greedy match to match 4 occurrences of digits.
(-[0-9]{2}){2} ##Matching - followed by 2 digits and this whole combination 2 times.
[[:space:]]+([0-9]{2}:){2} ##Matching space(s) followed by 2 digits followed by colon and this whole combination 2 times.
[0-9]{2}[^;]* ##Matching 2 digits and everything after it till a semi-colon comes.
我想从命令输出中 grep 一个字符串,但同时删除一个子字符串。例如
String = 活动:活动 (运行) 自星期六 2022-03-12 20:02:20 PKT; 1 小时 31 分钟前
我想要的 = 活动 (运行) 自 20:02:20 PKT
已删除
- 活跃:
- 2022-03-12 星期六
- ; 1 小时 31 分钟前
为此,我最初一直在使用正则表达式
sudo service sshd status |grep -Po '(?<=Active: )(.*) since (.*);'
active (running) since Mon 2022-03-14 01:06:43 PKT;
你能告诉我如何忽略日期和最后一个分号吗?同时只保留时间并输出完全一样:
active (running) since 01:06:43 PKT
谢谢
命令的完整输出:
● xrdp.service - xrdp daemon
Loaded: loaded (/lib/systemd/system/xrdp.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-03-14 01:06:44 PKT; 3 days ago
Docs: man:xrdp(8)
man:xrdp.ini(5)
Process: 668 ExecStartPre=/bin/sh /usr/share/xrdp/socksetup (code=exited, status=0/SUCCESS)
Process: 682 ExecStart=/usr/sbin/xrdp $XRDP_OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 687 (xrdp)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/xrdp.service
└─687 /usr/sbin/xrdp
systemd[1]: Starting xrdp daemon...
xrdp[682]: (682)(-1224841088)[DEBUG] Testing if xrdp can listen on 0.0.0.0 port 3389.
xrdp[682]: (682)(-1224841088)[DEBUG] Closed socket 7 (AF_INET6 :: port 3389)
systemd[1]: xrdp.service: Can't open PID file /run/xrdp/xrdp.pid (yet?) after start: No such file or directory```
你可以使用
sed -nE 's/^ *Active: +(.* since ).*([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*).*//p'
详情:
-nE
-n
抑制默认行输出并且E
启用 POSIX ERE 正则表达式语法^Active: +(.* since ).*([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*).*
- 查找匹配的行^ *Active: +
- 字符串的开头,零个或多个 spaces,Active:
和一个或多个 spaces(.* since )
- 第 1 组 (</code>):任意文本,然后是 space + <code>since
+ space.*
- 任何文本([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*)
- 两位数,:
,两位数,:
,两位数,然后是;
[=53= 以外的任何零个或多个字符].*
- 字符串的其余部分
</code> - 连接第 1 组和第 2 组值</li> <li><code>p
-p
打印替换结果。
#!/bin/bash
s=' Active: active (running) since Sat 2022-03-12 20:02:20 PKT; 1h 31min ago'
sed -nE 's/^ *Active: +(.* since ).*([0-9]{2}:[0-9]{2}:[0-9]{2}[^;]*).*//p' <<< "$s"
输出:
active (running) since 20:02:20 PKT
使用您显示的示例,请尝试以下 awk
代码。用 GNU awk
编写和测试。简单的解释是,创建一个名为 val
的 shell 变量并将其值发送到 awk
然后在 awk
程序中我使用 match
函数将正则表达式匹配到获取所需的值。
val="Active: active (running) since Sat 2022-03-12 20:02:20 PKT; 1h 31min ago"
echo "$val" |
awk '
match([=10=],/^Active:[[:space:]]+active \(running\)[[:space:]]+.*[0-9]{4}(-[0-9]{2}){2}[[:space:]]+([0-9]{2}:){2}[0-9]{2}[^;]*/){
val=substr([=10=],RSTART,RLENGTH)
sub(/^Active:[[:space:]]+/,"",val)
sub(/since[[:space:]]+\S+\s+\S+/,"since",val)
print val
}
'
正则表达式解释:
^Active:[[:space:]]+ ##Matching value starting from Active: followed by space(s).
active \(running\) ##matching active followed by a space followed by (running).
[[:space:]]+.*[0-9]{4} ##Matching 1 or more spaces then using greedy match to match 4 occurrences of digits.
(-[0-9]{2}){2} ##Matching - followed by 2 digits and this whole combination 2 times.
[[:space:]]+([0-9]{2}:){2} ##Matching space(s) followed by 2 digits followed by colon and this whole combination 2 times.
[0-9]{2}[^;]* ##Matching 2 digits and everything after it till a semi-colon comes.