说我有一些任意的多行文本文件:
sometext
moretext
lastline
如何在不使文本文件无效的情况下仅删除文件的最后一个字符(e,而不是换行符或null)?
Answers:
一个更简单的方法(将输出输出到stdout,不更新输入文件):
sed '$ s/.$//' somefile
$
是仅与最后输入行匹配的Sed地址,因此导致s/.$//
仅在最后一行执行以下函数调用()。s/.$//
用空字符串替换(在本例中为last)行的最后一个字符;即,有效地删除最后一个字符。(在换行符之前)。.
匹配该行上的任何字符,并在其后跟$
将匹配项锚定到该行的末尾;请注意,$
在此正则表达式中的使用在概念上是相关的,但在技术上与先前将其$
用作Sed地址不同。使用stdin输入的示例(假设Bash,Ksh或Zsh):
$ sed '$ s/.$//' <<< $'line one\nline two'
line one
line tw
要更新输入文件太多(如果输入文件是符号链接,不要使用):
sed -i '$ s/.$//' somefile
注意:
*在OSX上,您必须使用-i ''
而不是-i
; 有关相关陷阱的概述-i
,请参阅我的答案的下半部。
*如果您需要处理非常大的输入文件和/或性能/磁盘使用情况,并且您正在使用GNU实用程序(Linux),请参阅sorontar的有用答案。
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解决方案的问题sed '$ s/.$//' file
在于,它首先读取整个文件(大型文件需要很长时间),然后您需要一个临时文件(大小与原始文件相同):
sed '$ s/.$//' file > tempfile
rm file; mv tempfile file
然后移动临时文件以替换该文件。
如果目标是删除最后一行中的最后一个字符,awk
则应这样做:
awk '{a[NR]=$0} END {for (i=1;i<NR;i++) print a[i];sub(/.$/,"",a[NR]);print a[NR]}' file
sometext
moretext
lastlin
它将所有数据存储到一个数组中,然后将其打印出来并更改最后一行。
awk -i 'your code' file
编辑答案
我创建了一个脚本,并将您的文本放在桌面上。该测试文件另存为“ old_file.txt”
sometext
moretext
lastline
之后,我编写了一个小脚本来获取旧文件并消除最后一行中的最后一个字符
#!/bin/bash
no_of_new_line_characters=`wc '/root/Desktop/old_file.txt'|cut -d ' ' -f2`
let "no_of_lines=no_of_new_line_characters+1"
sed -n 1,"$no_of_new_line_characters"p '/root/Desktop/old_file.txt' > '/root/Desktop/my_new_file'
sed -n "$no_of_lines","$no_of_lines"p '/root/Desktop/old_file.txt'|sed 's/.$//g' >> '/root/Desktop/my_new_file'
打开我创建的new_file,显示如下输出:
sometext
moretext
lastlin
对于以前的回答,我深表歉意(没有仔细阅读)
sed 's/.$//' filename | tee newFilename
这应该做你的工作。