繁体   English   中英

sed命令删除单词的首次出现

[英]sed command to remove first occurrence of a word

我想知道如何删除文件中单词的第一次出现。

示例:我只想从第一次出现时删除管理员。

account    required       pam_opendirectory.so
account    sufficient     pam_self.so
account    required       pam_group.so no_warn group=admin,wheel fail_safe
account    required       pam_group.so no_warn deny group=admin,wheel ruser fail_safe

我努力了:

sudo sed -i.bak "s/admin,//1" /etc/pam.d/screensaver

但这消除了两种情况,有什么想法吗?

使用sed

要删除文件中的第一个匹配项:

$ sed -e ':a' -e '$!{N;ba;}' -e 's/admin,//1' file
account    required       pam_opendirectory.so
account    sufficient     pam_self.so
account    required       pam_group.so no_warn group=wheel fail_safe
account    required       pam_group.so no_warn deny group=admin,wheel ruser fail_safe

(以上已通过GNU sed测试。)

这个怎么运作

  • -e ':a' -e '$!{N;ba;}'

    这会立即将整个文件读入模式空间。 (如果您的文件太大而无法存储,则不是一个好方法。)

  • -e 's/admin,//1'

    这将对首次出现的admin和仅第一次出现的内容执行替换。

使用BSD(OSX)sed

Wintermute报告说BSD sed无法单行执行分支指令,并建议使用以下替代方法来更改文件:

sed -i.bak -n '1h; 1!H; $ { x; s/admin,//; p; }' file

这将立即读取整个文件,然后在读取最后一行后执行替换。

更详细地:

  • -n

    默认情况下,sed将打印每一行。 这关闭了。

  • 1h

    这会将第一行放置在保持缓冲区中。

  • 1!H

    对于所有后续行,这会将它们附加到保持缓冲区。

  • $ { x; s/admin,//; p; }

    对于最后一行($),这将交换保留和模式缓冲区,以便模式缓冲区现在具有完整的文件。 s/admin,//进行替换, p打印结果。

使用awk

$ awk '/admin/ && !f{sub(/admin,/, ""); f=1} 1' file >file.tmp && mv file.tmp file

结果是:

account    required       pam_opendirectory.so
account    sufficient     pam_self.so
account    required       pam_group.so no_warn group=wheel fail_safe
account    required       pam_group.so no_warn deny group=admin,wheel ruser fail_safe

这个怎么运作

  • /admin,/ && !f{sub(/admin,/, ""); f=1}

    对于每一行,请检查其是否包含单词admin,以及标志f仍具有默认值零。 如果是这样,请删除首次出现的admin,并将标志设置为一个。

  • 1

    打印每一行。 1是awk的{print $0}的简化形式。

使用sed,而不读取整个文件:

sed 's/admin,//;tl;b;:l;n;bl' file

这等待成功替换,然后进入打印文件其余部分的循环。

  • s/admin,//;tl;b; :用空字符串替换admin,如果发生替换,则跳转到标签l否则打印该行并退出(下一行将以相同的方式处理)。

  • :l;n;bl :定义标签l,读取行,跳至l。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM