![删除 root 拥有的任何用户的文件最后一行](https://linux22.com/image/217995/%E5%88%A0%E9%99%A4%20root%20%E6%8B%A5%E6%9C%89%E7%9A%84%E4%BB%BB%E4%BD%95%E7%94%A8%E6%88%B7%E7%9A%84%E6%96%87%E4%BB%B6%E6%9C%80%E5%90%8E%E4%B8%80%E8%A1%8C.png)
我有一个具有权限的文件666
,因此用户可以使用不同的脚本对其进行编辑。这有效。我需要编写脚本来删除文件的最后一行,但是这不能像使用sed
tris 之类的东西首先创建文件并将其移动到位一样工作。用户无法做到这一点。
有没有办法可以就地编辑文件以删除最后一行,而无需在其位置移动新文件?
答案1
由于该问题被标记为编辑,下面展示了如何使用编辑器以就地方式对文件进行编辑ed
:
printf '%s\n' d w q | ed -s file
当使用 启动编辑会话时ed
,编辑器始终将您置于打开文件的最后一行。要删除文件的最后一行,我们可以删除当前的使用 行d
,将修改后的缓冲区写回到文件中w
,然后使用 退出q
。编辑器的大多数实现ed
(但不是 BusyBox ed
)允许您使用非标准组合命令wq
来代替w
后跟q
。
这不会创建新文件(生成的文件与原始文件具有相同的索引节点号)。
答案2
您可以就地截断它。在 GNU 系统上:
truncate -s -"$(tail -n1 file | wc -c)" file
truncate -<n>
刮胡子<n>文件末尾的字节。这里<n>根据 所返回的最后一行的长度(以字节为单位)计算得出wc
。
可移植的是,您可以用来perl
进行截断:
tail -n1 file | perl -ne '
if (seek(STDOUT, -length, 2)) {
truncate STDOUT, tell STDOUT or die "truncate: $!\n"
} else {
die "seek: $!\n"
}' 1<> file
请注意,它不会重写文件的内容,因此比sed
基于 - 的方法更有效(并且在面对非文本文件或完整文件系统时也更安全)。
答案3
想通了,将常规 sed 命令的输出发送到用户的本地文件(临时文件),然后将文件作为输出发送到相关文件。
sed '$d' /path/to/file > ./tempfile; cat ./tempfile > /path/to/file
答案4
有一种方法可以在 sed 中使用“w”命令来完成此操作,而无需创建临时文件。这样文件的索引节点号就不会改变。更好的版本 B) 更易于使用,尤其是在脚本中,是首先将文件名分配给变量。
A) cat file|sed -ne '1h;${x;wfile' -e '};1!H'
B) file="test.txt";cat "$file"|sed -ne '1h;${x;w'"$file" -e '};1!H'
该文件被传递给 cat ,以便 sed 从管道读取输入,而不是直接从我们要修改的文件读取输入。 sed 读取的每个输入行都存储在保留空间中。但是,在输入结束时,在存储最后一行之前,将保留空间写入文件。