如何使用 ed 文本编辑器捕获具有不同第一个符号的 RegExp 第一个单词

如何使用 ed 文本编辑器捕获具有不同第一个符号的 RegExp 第一个单词

我有外壳命令:

printf '/^PermitRootLogin/\nc\nPermitRootLogin no\n.\nw\nq\n' | ed -s /etc/ssh/sshd_config

我需要在句子中使用此短语捕获#PermitRootLogin类似PermitRootLogin但未注释的段落,我正在使用 ed 文本编辑器并尝试找到某种方法来捕获命令中使用一个 RegExp 的所有出现情况。

我在这个操作系统上没有 GNU utils。谢谢你的答案!

答案1

正则表达式与 shell glob 模式不同。 ^?作为正则表达式没有有效的含义,因为^匹配行首并且?表示前面的子表达式的 0 或 1(在本例中为^)。

尝试这个:

grep `^.?SomeString`

解释:

^           anchors the match to the start of the line
.?          means 0 or 1 of any character
SomeString  match "Somestring"

答案2

A,, 和C是独立的命令;它们后面必须有文字在下一行。所以,你需要在之后换行C。你已经得到了\;看来您只是忘记了n

printf '/^PermitRootLogin/\nc\nPermitRootLogin 否\n。\nw\nq\n' | ed -s /etc/ssh/sshd_config

答案3

  1. 选择一个永远不会出现在配置文件中的任意字符串。最好避免使用/.*[等特殊字符]。例如,我将使用<G-Man>.
  2. 请执行下列操作:

    ed -s /etc/ssh/sshd_config << EOF
            g/^#*PermitRootLogin/s/^/<G-Man>/
            g/^<G-Man>##*PermitRootLogin...../s/<G-Man>//
            1,$s/^<G-Man>\(#*PermitRootLogin\).*/\1 no/
            w
            q
    EOF
    
  3. 这是做什么的?

    它找到每一行

    • 开头为PermitRootLogin, 或
    • 以一个或多个#字符开头,紧接着PermitRootLogin最多四个其他字符,

    并将其更改为PermitRootLogin no,将任何#字符保留在行首。

  4. 啊?什么?为什么要这样做?

    目标是改变以下任意一行:

    PermitRootLogin yes
    PermitRootLogin no
    PermitRootLogin The quick brown fox jumps over the lazy dog.
    #PermitRootLogin yes
    #PermitRootLogin no
    

    但不是以下几行:

    #In this section we set
    #PermitRootLogin to “maybe”,
    #because we haven’t decided yet.
    

    这种设计可能有一个不幸的副作用,即以下几行:

    ##PermitRootLogin yes
    ##PermitRootLogin ???
    

    将要进行更改,并添加以下行:

            PermitRootLogin yes
    # PermitRootLogin yes
            #PermitRootLogin yes
    

    将不会。

  5. 它是如何工作的?
    • g/^#*PermitRootLogin/s/^/<G-Man>/ 查找所有以 开头PermitRootLogin,或以一个或多个#字符开头,紧随其后的行PermitRootLogin,并用字符串“标记”它们<G-Man>(将其插入行的开头)。这将影响注释掉的行,前提是字符PermitRootLogin之前或之后没有空格(或其他任何内容) 。#
    • g/^<G-Man>##*PermitRootLogin...../s/<G-Man>// 查找所有带有标签的行最后一个 #开头,之后至少五个字符PermitRootLogin,并删除标签。这会取消PermitRootLogin长度超过 的注释行的标记 yes。 (当然你可以改变数量.如果你愿意的话。)
    • 1,$s/^<G-Man>\(#*PermitRootLogin\).*/\1 no/ 查找仍带有标记的所有行,删除标记,捕获PermitRootLogin和所有前面的#字符,保留它们,并将该行的其余部分替换为 no
  6. 当然,printf如果您愿意,您可以将这些命令折叠到 a 中。

相关内容