使用sed命令仅打印正则表达式匹配项

3

我希望你能帮我解决以下问题。

在我的Debian系统上,"timedatectl"的输出如下:

Local time: Wed 2022-11-16 13:02:00 CET
           Universal time: Wed 2022-11-16 12:02:00 UTC
                 RTC time: Wed 2022-11-16 12:02:01
                Time zone: Europe/Rome (CET, +0100)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no

我该如何使用sed命令仅获取“Europe/Rome”字符串或其他字符串?
我尝试了以下命令: timedatectl | sed -ne 's/^ *Time zone: \([A-z0-9_\/]*\).*$/\1/p' 但是会返回以下错误信息:

sed: -e expression #1, char 40: Invalid range end

请您提前多谢!

使用命令:sed -n 's~^ *时区: \([A-Za-z0-9_/]*\).*$~\1~p' - anubhava
2个回答

2
你的括号表达式包含了一个在当前排序规则下无法工作的 A-z 范围。如果在 sed 命令之前添加 LC_ALL=C,它不会出错,但它仍然会使它成为一个错误的正则表达式,因为 A-z ASCII 字符范围也匹配一些非字母符号。将 A-z0-9 替换为 [:alnum:] 是有意义的。
所以,你可以修复正则表达式,并使用 's/^ *Time zone: \([[:alnum:]_\/]*\).*$/\1/p' 或者只捕获任何非空格字符。
sed -n 's/^ *Time zone: \([^ ]*\).*/\1/p'

细节:
  • -n - 抑制默认的行输出
  • ^ *Time zone: \([^ ]*\).* - 找到以零或多个空格开头的行,然后有 Time zone:字符串,然后将除空格之外的任意数量的字符捕获到第1组中(使用\([^ ]*\)),并将该行的其余部分(使用.*)替换为匹配项,
  • \1 - 用第1组的值替换匹配项
  • p - 打印成功替换的结果
请参阅在线演示
#!/bin/bash
s='Local time: Wed 2022-11-16 13:02:00 CET
           Universal time: Wed 2022-11-16 12:02:00 UTC
                 RTC time: Wed 2022-11-16 12:02:01
                Time zone: Europe/Rome (CET, +0100)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no'
sed -n 's/^ *Time zone: \([^ ]*\).*$/\1/p' <<< "$s"

输出:

Europe/Rome

3
非常感谢您提供如此清晰的解释! - Robi

1
使用 sed
$ sed -En '/Time zone/s~[^/]* ([^ ]*).*~\1~p' input_file
Europe/Rome

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接