[英]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 -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
和仅第一次出现的内容执行替换。
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 '/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.