32

要删除所有可以删除的换行符,请说:

tr -d '\n' < days.txt
cat days.txt | tr -d '\n'

但是您将如何使用tr仅删除文本文件末尾/底部的换行符?

我不确定只指定最后一个。

4

6 回答 6

53

比公认的更简单的解决方案:

truncate -s -1 <<file>>

truncate手册页(man truncate):

-s, --size=SIZE
    set or adjust the file size by SIZE
SIZE may also be prefixed by one of the following modifying characters:
    '+' extend by, '-' reduce by, '<' at most, '>' at least, '/' round down
    to multiple of, '%' round up to multiple of.
于 2014-12-03T14:29:44.123 回答
31

利用以下事实:a)换行符位于文件末尾,b)字符大 1 个字节:使用truncate命令将文件缩小一个字节:

# a file with the word "test" in it, with a newline at the end (5 characters total)
$ cat foo 
test

# a hex dump of foo shows the '\n' at the end (0a)
$ xxd -p foo
746573740a

# and `stat` tells us the size of the file: 5 bytes (one for each character)
$ stat -c '%s' foo
5

# so we can use `truncate` to set the file size to 4 bytes instead
$ truncate -s 4 foo

# which will remove the newline at the end
$ xxd -p foo
74657374
$ cat foo
test$ 

您还可以将大小和数学转换为一行命令:

truncate -s $(($(stat -c '%s' foo)-1)) foo
于 2013-05-03T19:02:53.273 回答
26

如果您确定最后一个字符是换行符,那很简单:

head -c -1 days.txt

head -c -N表示除了最后 N 个字节之外的所有内容

于 2013-05-05T18:03:41.900 回答
14

我认为你最好的选择是 Perl:

perl -0pe 's/\n\Z//' days.txt

原因 perl将-0整个文件视为一个大字符串。-p告诉它在运行程序后将该字符串打印回来。并且-e说“这是要运行的程序”。

正则表达式\n\Z匹配换行符,但前提是它是字符串中的最后一个字符。并s/\n\Z//说用什么都没有替换这样的换行符,删除它。

上面的命令输出文件的新版本,但您可以通过添加-i("in-place") 选项来修改现有文件,可选地带有一个后缀,用于在修改文件之前命名文件的备份副本:

 perl -i.bak -0pe 's/\n\Z//' days.txt

这个解决方案是安全的,如果最后一个字符不是换行符,它就不会被触及。其他解决方案只是删除最后一个字节,无论什么可能损坏这样的文件。

于 2013-05-03T18:19:15.390 回答
8

试试这个命令: sed '$ { /^$/ d}' days.txt

您可以将其解读为:“检查最后一行是否为空行。如果是,请删除此行”。我对这两种情况都进行了测试:首先是一个文件末尾有一个新行,另一个是文件以其他内容结尾。

于 2013-05-04T07:12:55.020 回答
1

另一个 Sed 解决方案:

sed -z s/.$// days.txt

使用该-z选项,它将文件解释为单个长行(换行符嵌入为\n),然后s匹配.行尾(=文件结尾)之前的单个字符$,并将其更改为空。无需引用命令。

如果您不确定最后一个字符是换行符,那么您可以执行以下任一操作:

sed -z s/\\n$// days.txt
sed -z 's/\n$//' days.txt
于 2020-09-07T12:11:27.057 回答