如何删除unix中文件的最后一个字符?

说我有一些任意的多行文本文件:

sometext moretext lastline 

我怎样才能删除文件的最后一个字符(e,而不是换行符或空),而不使文本文件无效?

Solutions Collecting From Web of "如何删除unix中文件的最后一个字符?"

一个更简单的方法( 输出到标准输出 ,不更新输入文件):

 sed '$ s/.$//' somefile 
  • $是一个Sed地址,它只与最后一行相匹配,因此在最后一行上执行下面的函数调用( s/.$// )。
  • s/.$//用一个空字符串替换(在这种情况下是最后一行)的最后一个字符; 即有效地去除最后一个字符。 (换行之前)就行了。
    . 匹配该行上的任何字符,并用$将该匹配锚定到该行的末尾; 注意这个正则表达式$的使用是如何在概念上相关的,但是在技术上与前面使用$作为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 

这工作,因为尾部采取最后一个字节(不是字符)。

即使是大文件也几乎没有时间。

为什么不sed

sed '$ s/.$//' file这样的sed解决方案的问题是,它首先读取整个文件(花费很长时间处理大文件),那么您需要一个临时文件(与原文件大小相同):

 sed '$ s/.$//' file > tempfile rm file; mv tempfile file 

然后移动tempfile来替换文件。

这是另一个使用ex ,我觉得不像sed解决方案神秘:

  printf '%s\n' '$' 's/.$//' wq | ex somefile 

$到最后一行, s删除最后一个字符, wq是众所周知的(vi用户)write + quit。

在玩了很多不同的策略(并避免sed -i或perl)之后,我发现这样做的最好方法是:

 sed '$! { P; D; }; s/.$//' somefile 

如果目标是删除最后一行中的最后一个字符,那么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 

它将所有数据存储到数组中,然后将其打印出来并更改最后一行。

编辑答案

我创建了一个脚本,并将您的文本放在我的桌面上。 这个测试文件保存为“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会暂时删除文件。 所以,如果你拖尾文件,你会得到一个“没有这样的文件或目录”警告,直到你重新发出tail命令。

sed 's/.$//' filename | tee newFilename

这应该做你的工作。