sed 原地替换文件时遇到的趣事

哈喽大家好,我是咸鱼

在文章《三剑客之 sed》中咸鱼向大家介绍了文本三剑客中的 sed

sed 全名叫 stream editor,流编辑器,用程序的方式来编辑文本

那么今天咸鱼打算讲一下我在用 sed 原地替换文件时遇到的趣事

sed 让文件属性变了?

有这么一个普通文件 test.txt ,内容如下:

csharp 复制代码
[root@localhost /opt]# cat test.txt 
My name is Ammon
hello world!
hahahahaha

link_test.txt 是一个软链接(Symbolic Link,也可以叫符号链接)文件,指向 test.txt 文件

软链接文件类似于 Windows 的快捷方式,它实际上是一个特殊的文件。关于软链接相关的内容这里不过多介绍

如果我们对软链接文件内容进行修改,源文件是会跟着改变的

当我使用 sed 对软链接文件link_test.txt 进行内容修改时,命令如下

arduino 复制代码
[root@localhost /opt]# sed -i 's/Ammon/Edsion/g' link_test.txt 

有趣的现象发生了:使用 sed 对软链接文件link_test.txt 进行内容修改之后,源文件test.txt内容没有变化,软链接文件link_test.txt 的内容发生变化且变成了普通文件

怎么样,是不是很神奇?sed 不但把文件内容改了,还把文件属性也给改了

我们用 strace 工具来查看一下在执行 sed 命令时操作系统做了哪些操作

strace 一个系统调用跟踪工具,它会跟踪并记录命令运行期间的系统调用和信号

arduino 复制代码
[root@localhost /opt]# strace sed -i 's/Ammon/Edsion/g' link_test.txt > strace.log 2>&1

具体内容有点多,我们着重看下关键内容

由上图可以知道,如果我们使用 sed 对一个文件进行原地替换,需要有一个临时文件,sed 先把修改内容写入到这个文件,最后将文件 rename 到原来的地方

那我的需求是对软链接文件 link_test.txt 进行内容修改,软链接文件属性不变,且源文件的内容也跟着改变,有没有什么方法呢?

也就是说我们希望命令在执行的时候能够解析出来软链接文件后面指向的源文件,直接对源文件进行读--处理--写,最后 rename

sed 命令有一个选项 --follow-symlinks

sql 复制代码
--follow-symlinks: 
    follow symlinks when processing in place

我们在执行的时候加上这个选项:

css 复制代码
[root@localhost /opt]# strace sed -i --follow-symlinks 's/Ammon/Edsion/g' link_test.txt > strace.log 2>&1

总结一下:

  • sed 替换的底层逻辑是把更新后的内容写入一个临时文件里面,然后再 rename 这个临时文件
  • 这样就会使得如果没有添加 --follow-symlinks 选项的话,对软链接文件进行 sed 操作就会使得软链文件变成了一个常规文件(其实是那个临时文件重命名导致的)
  • 如果要对软链接文件指向的源文件进行操作,就需要添加 --follow-symlinks 选项
相关推荐
小安运维日记3 分钟前
RHCA - DO374 | Day01:使用红帽Ansible自动化平台开发剧本
运维·服务器·云原生·自动化·云计算·ansible
刘岩Tony25 分钟前
ssh别名和多服务器同步文件
运维·服务器·ssh
zzy208874027125 分钟前
自定义服务器实现时间同步
运维·服务器
LXY_BUAA29 分钟前
在电脑中安装双系统(win11 + linux)20251019
linux·运维·服务器
小白银子1 小时前
零基础从头教学Linux(Day 54)
linux·windows·python
---学无止境---1 小时前
Linux中inode节点号的获取相关函数的实现
linux
一文解千机1 小时前
Termux 安装盘搜搜PanSou,快速找到网盘资源链接,支持各大网盘,自定义部署,数据存储到手机,打造移动搜索资源库
linux·termux·盘搜搜·pansou·资源搜索·网盘资源链接搜索·手机网盘搜索
小蜗快跑丶2 小时前
内网构建https
运维·服务器
啊森要自信2 小时前
【MySQL 数据库】使用C语言操作MySQL
linux·c语言·开发语言·数据库·mysql
做运维的阿瑞2 小时前
DevOps 生命周期完全指南
运维·容器·devops