【问题标题】:Remove from file a string and another string and everything after it从文件中删除一个字符串和另一个字符串以及之后的所有内容
【发布时间】:2021-08-20 20:01:56
【问题描述】:

假设我有一个文件teams,内容如下:

[Desktop Entry]
Version=1.0
Type=Application
Name=Microsoft Teams - Preview
Comment=Microsoft Teams for Linux is your chat-centered workspace in Office 365.
Exec=teams %U
Icon=teams
Terminal=false
StartupNotify=true
StartupWMClass=Microsoft Teams - Preview
Categories=Network;
MimeType=x-scheme-handler/msteams;
X-KDE-Protocols=teams
Actions=QuitTeams;
X-GNOME-UsesNotifications=true;

[Desktop Action QuitTeams]
Name=Quit Teams

我想删除一行Actions=QuitTeams;。这似乎很容易:

sed -i '/Actions=QuitTeams;/d' teams

另外,我想删除一行 [Desktop Action QuitTeams] 及其后面的所有内容(可能有新行)。 这似乎也很容易:

sed -i '/[Desktop Action QuitTeams]]/,$d' teams

我的问题是:我如何在一次 sed 执行中完成这两个步骤,即将所有正则表达式合并为一个? Sed 是首选,但也欢迎使用其他工具。

【问题讨论】:

    标签: linux sed text-parsing in-place


    【解决方案1】:

    您可以尝试使用sed-e 选项(参见3.8 Multiple commands syntax):

    $ sed -i -e '/Actions=QuitTeams;/d' -e '/[Desktop Action QuitTeams]]/,$d' teams
    $ cat teams
    [Desktop Entry]
    Version=1.0
    Type=Application
    Name=Microsoft Teams - Preview
    Comment=Microsoft Teams for Linux is your chat-centered workspace in Office 365.
    Exec=teams %U
    Icon=teams
    Terminal=false
    StartupNotify=true
    StartupWMClass=Microsoft Teams - Preview
    Categories=Network;
    MimeType=x-scheme-handler/msteams;
    X-KDE-Protocols=teams
    X-GNOME-UsesNotifications=true;
    

    【讨论】:

    • 或者使用 GNU sed,您可以使用 ';' 链接表达式,例如sed -i '/Actions=QuitTeams;/d;/\[Desktop Action QuitTeams\]/,/^$/d' file(略有不同,它从 [Desktop Action QuitTeams] 删除到下一个空行——以防它不在文件末尾)
    【解决方案2】:

    您按原样使用-i 就地修改选项,因此您使用的是 GNU sed。在 GNU sed 中,您还可以使用

    sed -z -i 's/[^\n]*Actions=QuitTeams;[^\n]*\n\?\|[^\n]*\[Desktop Action QuitTeams].*//g' teams
    

    请参阅online demo

    -z 选项会删除行尾,并且行尾对正则表达式“可见”。

    sed 正则表达式是符合 POSIX BRE 的匹配模式

    • [^\n]* - LF 以外的零个或多个字符
    • Actions=QuitTeams; - Actions=QuitTeams; 字符串
    • [^\n]*\n\? - 除 LF 以外的零个或多个字符,然后是可选的 LF 字符
    • \| - 运算符或
    • [^\n]* - LF 以外的零个或多个字符
    • \[Desktop Action QuitTeams] - [Desktop Action QuitTeams] 字符串(注意转义的 [ 以免定义括号表达式)
    • .* - 文件末尾之前的任何文本(因为 POSIX 正则表达式中的 . 匹配任何字符,包括换行字符)。

    【讨论】:

    • 虽然可以将两个表达式放在一个正则表达式中,但上面的多个 -e 选项更加清晰且易于维护。
    • @AndyLester 我同意,只是 OP 要求“将所有正则表达式组合成一个”,不幸的是它可能看起来像这样。
    • 我怀疑“将所有正则表达式合并为一个”是因为 OP 不知道他们可以使用多个 -e
    猜你喜欢
    • 2022-08-19
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多