我已经看过很多关于这个问题的例子,但还没有看到为我量身定做的那个 . 虽然我对sed非常熟悉,但是当谈到更高级的功能时,我很惭愧地说我是个菜鸟 . 这是手头的问题 .
我有一个多线模式,我可以像这样成功地匹配sed,
sed -e '/Favorite Animals/, /!/p
Favorite Animals
Monkey
Penguin
Cat
!
Favorite Things
Shoe
Dog
Wheel
Moth
!
我个人喜欢这个表达式的是我可以将可变数量的行匹配到感叹号 . 现在让我们说我想进行搜索并替换相同的模式 . 基本上我想用我选择的任何字符串替换之前演示过的多行模式 . 有任何想法吗?我希望我的sed命令具有类似的语法,但乞丐不能选择 .
我的想法是,我可以用字符串替换感叹号分隔的其中一个组 . 我称之为“条目” . 我希望能够更新或覆盖这些条目 . 如果我有一个最喜欢的动物的更新版本,我希望能够用这样的新条目替换旧条目 .
Favorite Animals
Sloth
Platypus
Badger
Dog
!
Favorite Things
Shoe
Dog
Wheel
Moth
!
如你所见,我现在不再是猴子的粉丝了 .
2 回答
有多种选择 - 可以使用
i
,c
和a
命令 .修改后的答案
此修订的答案处理现在问题中的修改数据文件 . 这是修改后的
data
文件的温和增强版本:所有这三个
sed
脚本都产生相同的输出:样本输出:
至关重要的是脚本都使用唯一字符串
/Favourite Animals/
并且不要键入重复的尾随上下文/!/
. 如果i
或a
使用/!/
而不是/Favourite Animals/
,则输出会发生变化 - 而不是更好 ./!/i
:/!/a
:额外请求
当然是 . 对于单个映射:
对于多个映射:
如果您愿意,也可以将它们组合到一行 - 使用分号分隔它们:
请注意,GNU
sed
和BSD(Mac OS X)sed
对最后一个分号的必要性有不同的看法 - 显示的内容对两者都有效 .原始答案适用于更简单的输入文件 .
原始答案
考虑包含以下内容的文件
data
:使用
c
,您可能会写:使用
i
,您将使用:使用
a
,您可以写:请注意:
c
- 您更改了整个范围i
- 在删除整个范围之前插入范围中的第一个模式之前a
- 在删除整个范围之前,在范围中的最后一个模式之后追加但是,考虑到它,您可以在删除整个范围之前插入范围中的最后一个模式之前,或者在删除整个范围之前追加范围中的第一个模式之后 . 因此,
i
和a
的键是在基于范围的删除之前放置'replacement text'操作 . 但是c
是最简洁的 .i
(插入)命令具有丑陋的语法,但它的工作原理如下: