【问题标题】:Grep string and remove 1st characterGrep 字符串并删除第一个字符
【发布时间】:2012-11-27 18:27:59
【问题描述】:

我想在 grep 某个字符串时删除文件中的第一个字符。但需要在编辑之前将更改的行放在同一位置。

示例文件:

#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth           sufficient      pam_wheel.so trust use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet

编辑后的预期视图:

#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
auth           sufficient      pam_wheel.so trust use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet

在这种情况下,第 4 行只需要删除“#”,但我想在搜索字符串“sufficient pam_wheel.so trust use_uid”时这样做,而不是指向我要编辑的确切行。

【问题讨论】:

    标签: sed awk grep tr


    【解决方案1】:

    这是sed的工作:

    $ sed -r 's/^#(.*sufficient\s+pam_wheel\.so trust use_uid.*)/\1/' file
    #%PAM-1.0
    auth            sufficient      pam_rootok.so
    # Uncomment the following line to implicitly trust users in the "wheel" group.
    auth           sufficient      pam_wheel.so trust use_uid
    auth            include         system-auth
    account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet
    

    正则解释:

    s/                            # Substitute  
    ^#                            # A line starting with a #
    (                             # Start capture group
    .*                            # Followed by anything
    sufficient                    # Followed by the word sufficient
    \s+                           # Followed by whitespace
    pam_wheel\.so trust use_uid   # Followed by the literal string (escaped .)
    .*                            # Followed by anything
    )                             # Stop capture group
    /                             # Replace with 
    \1                            # The first capture group 
    

    因此,我们有效地匹配了以 # 开头的包含字符串 sufficient\s+pam_wheel.so trust use_uid 的行并删除了 #

    注意:-r 标志用于扩展正则表达式,对于您的sed 版本,它可能是-E,因此请检查man

    如果要将更改存储回file,请使用-i 选项:

    $ sed -ri 's/^#(.*sufficient\s+pam_wheel\.so trust use_uid.*)/\1/' file
    

    如果列对齐很重要,则最多捕获 sufficient 并在其后捕获 2 个捕获组并替换为 \1 \2

    $ sed -r 's/^#(.*)(sufficient\s+pam_wheel\.so trust use_uid.*)/\1 \2/' file
    #%PAM-1.0
    auth            sufficient      pam_rootok.so
    # Uncomment the following line to implicitly trust users in the "wheel" group.
    auth            sufficient      pam_wheel.so trust use_uid
    auth            include         system-auth
    account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet
    

    编辑:

    #AllowUsers support admin替换字符串AllowUsers support admin

    $ sed -r 's/^(AllowUsers support admin.*)/#\1/' file
    #AllowUsers support admin
    
    $ sed -r 's/^(DeniedUsers root.*)/#\1/' file
    #DeniedUsers root
    

    【讨论】:

    • 如果我有文件的另一种情况:AllowUsers support admin 如何使该文件成为:#AllowUsers support adminDeniedUsers root
    • 实际上 DeniedUsers 根在新行上,替换包含 AllowUsers 的整行可能很好
    • 好吧,我为自己找到了解决方案:sed -r 's/(AllowUsers.*)/#\1 \nDeniedUsers root/' 谢谢,@sudo_O
    • 现在我看到你的代码明白了,是的,这就是我会做的。
    【解决方案2】:

    使用 awk 你可以做到:

    awk -F '#' '{ if ($0 ~ /^#.*sufficient +pam_wheel.so trust use_uid/) {$1=""; print;} else print}'  infile
    

    OR(如果开头只能有一个#):

    awk -F '#' '{ if ($0 ~ /^#.*sufficient +pam_wheel.so trust use_uid/) print $2; else print}'  infile
    

    【讨论】:

    • 引用but I want to do that when search the string "sufficient pam_wheel.so trust use_uid" not when point the exact row that I want to edit
    • @sudo_O:感谢您指出这一点,尽管它仍然可以在一个简单的 awk 命令中完成。请立即检查编辑后的答案。
    • 更好,但您只打印没有# 的匹配行,如果不打印文件中的所有行,这不是很有用。
    • @sudo_O:谢谢,也解决了这个问题
    • 好,需要指出的是,使用awk需要重定向才能对文件awk '{...}' file > new_fileawk '{...}' file > tmp; mv tmp file进行更改
    【解决方案3】:

    这是使用sed的一种方式:

    sed '/sufficient \+pam_wheel.so \+trust \+use_uid/s/^#//' file
    

    结果:

    #%PAM-1.0
    auth            sufficient      pam_rootok.so
    # Uncomment the following line to implicitly trust users in the "wheel" group.
    auth           sufficient      pam_wheel.so trust use_uid
    auth            include         system-auth
    account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet
    

    【讨论】:

      【解决方案4】:
      perl -pi -e '$_=~s/^.//g if(/sufficient      pam_wheel.so trust use_uid/)' your_file
      

      注意:这将进行就地替换。所以在您运行命令后,您的文件将被自动修改。

      【讨论】:

        【解决方案5】:

        sed 命令只能进行 RE 匹配而不是字符串比较,因此要使用 sed,您需要解析所需的字符串以转义所有容易出错的 RE 元字符(例如,当前发布的解决方案都忽略了转义“。”在pam_wheel.so)。

        当您尝试匹配字符串时,最好只进行字符串比较,例如:

        awk 'index($0,"sufficient pam_wheel.so trust use_uid"){sub/^#/,"")}1' file > tmp && mv tmp file
        

        【讨论】:

          猜你喜欢
          • 2011-06-24
          • 2011-05-29
          • 1970-01-01
          • 1970-01-01
          • 2021-10-22
          • 1970-01-01
          • 2013-07-05
          • 1970-01-01
          相关资源
          最近更新 更多