假设我有一些任意的多行文本文件:
sometext
moretext
lastline
如何仅删除文件的最后一个字符(e,而不是换行符或 null)而不使文本文件无效?
原文由 MaxPRafferty 发布,翻译遵循 CC BY-SA 4.0 许可协议
假设我有一些任意的多行文本文件:
sometext
moretext
lastline
如何仅删除文件的最后一个字符(e,而不是换行符或 null)而不使文本文件无效?
原文由 MaxPRafferty 发布,翻译遵循 CC BY-SA 4.0 许可协议
truncate
truncate -s-1 file
从同一文件的末尾删除一个 (-1) 字符。就像 >>
一样,将附加到同一个文件。
这种方法的问题在于,如果它存在,它不会保留尾随换行符。
解决方案是:
if [ -n "$(tail -c1 file)" ] # if the file has not a trailing new line.
then
truncate -s-1 file # remove one char as the question request.
else
truncate -s-2 file # remove the last two characters
echo "" >> file # add the trailing new line back
fi
这是有效的,因为 tail 采用最后一个字节(而不是 char)。
即使是大文件也几乎不需要时间。
为什么不 sed
像 sed '$ s/.$//' file
这样的 sed 解决方案的问题在于它首先读取整个文件(大文件需要很长时间),然后您需要一个临时文件(与原始文件大小相同):
sed '$ s/.$//' file > tempfile
rm file; mv tempfile file
然后移动临时文件以替换文件。
原文由 user8017719 发布,翻译遵循 CC BY-SA 3.0 许可协议
7 回答5.3k 阅读
4 回答4k 阅读
2 回答5.9k 阅读✓ 已解决
2 回答2.5k 阅读✓ 已解决
1 回答2.3k 阅读✓ 已解决
2 回答795 阅读✓ 已解决
2 回答3.2k 阅读
一种更简单的方法( 输出到 stdout ,不更新输入文件):
$
是一个仅匹配最后一个输入行的 Sed 地址,因此导致以下函数调用(s/.$//
)仅在最后一行执行。s/.$//
用空字符串替换(在本例中为 last )行的最后一个字符;即,有效地删除最后一个字符。 (在换行符之前)就行了。.
匹配行中的任何字符,并在其后跟$
将匹配锚定到行尾;注意$
在这个 正则表达式 中的使用在概念上是相关的,但在技术上与之前使用$
作为 Sed 地址 不同。要 _更新输入文件_(如果输入文件是符号链接,则不要使用):
笔记:
-i ''
而不仅仅是-i
;有关与-i
相关的陷阱的概述,请参阅 此答案 的下半部分。