请问linux下通过bashshell如何替换文件中的几行文件,用另一部分文本代替?

沉思的归零者 2020-07-21 04:52:13
举例说明:
file.txt内容有:

aaa
### config-start ###
bbb
ccc
ddd
### config-end ###
eee


希望替换为

aaa
### config-start ###
111
222
333
### config-end ###
eee


也就是把file.txt中指定的内容(config-start和config-end之间的所有内容),替换为另一部分内容,这另一部分内容可能也是有多行或特殊符号的,然后指定的内容以外的内容,不能动,
也不能删除后追加到文件末尾,
我想通过sed实现,但始终没有找到办法,望高手赐教。
...全文
20767 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
沉思的归零者 2020-08-17
  • 打赏
  • 举报
回复
大哥,没有想到sed还有如此高深莫测的用法,你这寥寥几行,就够我消化一阵了,我先研究下
alittlenewbiek 2020-08-02
  • 打赏
  • 举报
回复
可以有其它两种方法
# 创建两个文件
cat <<EOF > file1
aaa
### config-start ###
bbb
ccc
ddd
### config-end ###
eee
EOF

cat <<EOF > file2
123
456
789
EOF

第一种,适合替换内容不多、能手打出来的
sed '
/bbb/,/ddd/c\
123\n456\n789
' file1
# 或者
sed '
/bbb/,/ddd/c\
987\
654\
321
' file1

说明:
'c\'
'TEXT'
接收两个地址,把两个地址确定的范围内的内容删除,并替换接下来的TEXT
    TEXT的每一行用\结尾,但最后一行不需要用\
可以使用转义字符
P.S. 也可以使用a\ TEXT,不过需要多几个步骤

第二种方法,适合从其它文件摘取几行内容,大范围替换
sed -n '1,3p' file2 | sed -e '3r /dev/stdin' -e '3,5d' file1
# or anything
echo -e "hello\nworld" | sed -e '3r /dev/stdin' -e '3,5d' file1
# or directly from file
sed -e '3r file2' -e '3,5d' file1

说明:
主要使用r FILENAME命令,'/dev/stdin'是GNU sed才可以使用的特殊文件名,表示从标准输入读取,适合piping。
r先将文件内容缓存起来,当sed处理完一个轮回之后,便把缓存的内容输出
由于d命令会强制开始下一轮,所以先使用r再使用d
P.S. 所谓轮回(cycle),sed有两个缓冲区叫pattern和hold,
sed每次从输入流那里读取一行、并放入pattern buffer中,
如果该行匹配上了定位符(address,比如行号、正则表达式/REGEXP/),就使用命令处理该行,
如果没有指定address,默认处理每一行;
一般如果没有使用-n选项的话,最后一行命令处理完之后,把pattern buffer的内容打印出来;
开始下一轮
品牌 2020-07-22
  • 打赏
  • 举报
回复
sed '/star/{:A;N;/end/!s/\n.*/\n111\n2222\n3333/;tA}'

测试:
# echo 'aaa
### config-start ###
bbb
ccc
ddd
### config-end ###
eee'|sed '/star/{:A;N;/end/!s/\n.*/\n111\n2222\n3333/;tA}'
aaa
### config-start ###
111
2222
3333
### config-end ###
eee

19,612

社区成员

发帖
与我相关
我的任务
社区描述
系统使用、管理、维护问题。可以是Ubuntu, Fedora, Unix等等
社区管理员
  • 系统维护与使用区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧