【问题标题】:sed substitution - do not modify for a particular casesed 替换 - 不要针对特定​​情况进行修改
【发布时间】:2020-03-01 11:33:06
【问题描述】:

我有一个文件有很多行是这样写的 -

random text
some info, command -task shoot and more info
some info, command -new_task shoot and more info
more info and shoot a lot
command -task shoot and some more info and shoot a lot

我希望shoot 的首字母大写,command -* shoot 除外。

所以替换后我的文件应该是这样的 -

random text
some info, command -task shoot and more info
some info, command -new_task shoot and more info
more info and Shoot a lot
command -task shoot and some more info and Shoot a lot

我为此编写了以下脚本 -

var="shoot";
sed -i "/-.*?${var}/ ! s/ ${var} / ${var^} /g" file;

除了command -* shootshoot 写在同一行之外,这个脚本工作正常。在这种情况下,我得到的输出为 -

command -task Shoot and some more info and Shoot a lot

在这种情况下,shoot 都成为大写字母,这是不可取的。 有什么办法可以解决这个问题吗?

【问题讨论】:

  • command - 后面可以有哪些字符?除了空间或特定集合之外的一切?
  • 只有一组特定的字符:-task、-start_task 和 -end_task,但我正在考虑编写更通用的 sed 命令形式。无论如何,如果只有这 3 种情况,解决办法是什么?
  • 我可能会像sed 's/shoot/\u&/g; s/\(command -[^ ]* \)Shoot/\1shoot/g' file 那样做某事,但我并不是说这是最好的方法
  • 谢谢@oguzismail。这非常有效,我想不出比这更好的解决方案。

标签: unix sed scripting


【解决方案1】:

该任务似乎需要某种形式的回顾,其中每次替换都以前两个标记为条件(不能匹配'command -*')。如上所述,单一条件下的简单全局替换不适用于

command -task shoot and some more info and shoot a lot

鉴于sed 相对严格的流程,并且缺乏复杂的条件、变量,可能更容易利用 sed 管道,并将其构建为一系列命令:

  1. 对每个“命令 -* 射击”进行编码以隐藏它们以防止下一步替换
  2. 全局替换剩余的shoot(用空格括起来)
  3. 恢复“隐藏”的短裤。
sed -e 's/\(command -[^ ]\+ \)shoot /\1@shoot /' -e 's/ shoot / Shoot /' -e 's/ @shoot / shoot /'

“隐藏”是通过在shoot 之前插入@ 来实现的。

命令选项 (-*) 的模式可以针对更多受限字符集进行调整

可以根据 Jotne 的建议将 3 '-e' 组合成单个脚本,并使用扩展 RE,以简化命令:

sed -r 's/(command -[^ ]+ )shoot /\1@shoot /;s/ shoot / Shoot /;s/ @shoot / shoot /'

【讨论】:

  • 看起来正确。您可以使用-r 来避免转义,并且您可以加入所有操作使用; 而不是' -e ',因此您会得到sed -r 's/(command -[^ ]+ )shoot /\1@shoot /;s/ shoot / Shoot /;s/ @shoot / shoot /' file
  • s/ shoot / Shoot / 更改为s/ shoot / Shoot /g 以获得更多shoot 在同一行。 (可能存在)
  • 谢谢@dash-o。 @oguzismail 在 cmets 中针对该问题提供了类似的解决方案。以下是他的解决方案——sed 's/shoot/\u&/g; s/\(command -[^ ]* \)Shoot/\1shoot/g' file
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-19
相关资源
最近更新 更多