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

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

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

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

#1楼 票数:4 已采纳

使用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}的简化形式。

#2楼 票数:0

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

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

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

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

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

  ask by Technic1an translate from so

未解决问题?本站智能推荐:

6回复

SED命令删除空行直到第一次出现句子

我的输入文件将是 这里[emptyline]表示空白行。 我需要一个SED命令来改变它 也就是说,我需要单独删除顶部的所有空行。 我只需要SED命令,因为我需要在bash脚本中使用它。 其他信息其MAC OSx
4回复

如何在OSX中使用sed将每个单词的首字母大写

我正在尝试使用以下sed命令将字符串中每个单词的首字母大写,但无法正常工作: 输出: 我究竟做错了什么? 谢谢
2回复

使用“ sed”将第一次出现的打开/关闭XML标签替换为另一个标签名称

如果我有一个如下所示的XML: 我如何告诉sed(在Mac上)仅将<c> ... </ c>的第一次出现更改为<e> ... </ e>,同时仍然保留介于两者之间的内容(\\ 1)开始和结束标签? 谢谢
2回复

sed:c命令,仅更改第一行,删除文本

我正在进行Shell脚本的第二天,我偶然发现了这个问题:我想更改一整行代码,我只用一个字来标识,并且只想在第一次出现时才这样做。 我正在使用sed和c命令,如下所示: 名为“ prova”的文件中的文本: sed代码: (我使用的是Mac OSX) 足够奇怪的是
1回复

sed命令,仅在第一次出现后才添加特定工作后的文本

我想在文件中的特定单词之后添加一些单词。 例: 我想在“ flags:ia”之后添加,lo,ad,fd,fm,全部使用以下see命令: 但是我的输出最终是 我怎样才能使其仅影响“ flags:”而不影响“ naflags:”?
3回复

Sed 和 Mac OS 终端:如何从每个文件的第一行中删除括号内容?

我在 Mac Os 10.14.6 上有一个目录,其中包含所有包含文本文件的子目录。 总共有数百个文本文件。 我想浏览文本文件并检查括号中第一行中的任何内容。 如果找到此类内容,则应删除括号(和括号中的内容)。 例子: 拆除前: 移除后: 我该怎么做? 我尝试过的步骤: 谷
1回复

如何使用sed替换“word{word”或“word}word”

我尝试编写一个 bash 脚本来替换以下内容: 在子文件夹的所有CSV文件中。 这是我目前使用的: 不知何故,我无法让它工作。 该脚本正在替换没有"或}或,文本,但不会替换上面列出的单词。
5回复

在sed中拆分第二次出现的骆驼样式文本的模式

我正在尝试使用sed和awk为mac应用程序创建键,值字符串表。 到目前为止,我已经理解到了像这样的行: 我想做最后一步来获得: 换句话说,将第二次出现的骆驼文本拆分开。 我已经看到sed是这样的: 哪个将全局执行,然后使用以下命令进行第二次匹配: 还是第三次