如何从文件的最后一行删除换行符以便向该行添加文本?

Pan*_*dya 77 shell-script text-processing newlines

假设我有一个名为file

$ cat file
Hello
Welcome to
Unix
Run Code Online (Sandbox Code Playgroud)

我想and Linux在文件最后一行的末尾添加。如果我这样做echo " and Linux" >> file将被添加到一个新行。但我想要最后一行Unix and Linux

所以,为了解决这个问题,我想删除文件末尾的换行符。因此,如何删除文件末尾的换行符以便向该行添加文本?

Gil*_*il' 73

如果您只想在最后一行添加文本,使用 sed 非常容易。$仅在范围内的行$(即最后一行)替换(行尾的模式匹配)为您要添加的文本。

sed '$ s/$/ and Linux/' <file >file.new &&
mv file.new file
Run Code Online (Sandbox Code Playgroud)

在 Linux 上可以缩短为

sed -i '$ s/$/ and Linux/' file
Run Code Online (Sandbox Code Playgroud)

如果您想删除文件中的最后一个字节,Linux(更准确地说是 GNU coreutils)提供了该truncate命令,这使得这很容易。

truncate -s -1 file
Run Code Online (Sandbox Code Playgroud)

一种 POSIX 方法是使用dd. 首先确定文件长度,然后将其截断为少一个字节。

length=$(wc -c <file)
dd if=/dev/null of=file obs="$((length-1))" seek=1
Run Code Online (Sandbox Code Playgroud)

请注意,这两者都会无条件地截断文件的最后一个字节。您可能想先检查它是否是换行符:

length=$(wc -c <file)
if [ "$length" -ne 0 ] && [ -z "$(tail -c -1 <file)" ]; then
  # The file ends with a newline or null
  dd if=/dev/null of=file obs="$((length-1))" seek=1
fi
Run Code Online (Sandbox Code Playgroud)

  • 更好[删除尾随换行符的方法](/sf/answers/115782971/#how-can-i-delete-a-newline-if-it-is-the-last-character-in -a-file) 是 `perl -pi -e 'chomp if eof' myfile`。与 `truncate` 或 `dd` 相比,如果 `myfile` 实际上没有尾随换行符,它不会给你留下一个损坏的文件。 (15认同)
  • @Hi-Angel 我可以建议把它写成答案吗?我认为这将是一个非常好的答案。 (2认同)

Pan*_*dya 40

不过,您可以通过tr -d '\n'以下方式从行中删除换行符:

$ echo -e "Hello"
Hello
$ echo -e "Hello" | tr -d '\n'
Hello$
Run Code Online (Sandbox Code Playgroud)

您可以使用以下简单方法删除文件末尾的换行符:

  1. head -c -1 file

    来自man head

    -c, --bytes=[-]K
              print the first K bytes of each file; with the leading '-',
              print all but the last K bytes of each file
    
    Run Code Online (Sandbox Code Playgroud)
  2. truncate -s -1 file

    来自man truncate

    -s, --size=SIZE
              set or adjust the file size by SIZE
    
    Run Code Online (Sandbox Code Playgroud)

    SIZE is an integer and optional unit (example: 10M is 10*1024*1024).
    Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of 1000).
    
    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.
    
    Run Code Online (Sandbox Code Playgroud)

  • 这不会删除最后一个换行符,而是删除所有换行符。IMO 有很大的不同。 (5认同)

Hi-*_*gel 35

您可以使用 perl 实现此目的:

perl -pi -e 'chomp if eof' myfile
Run Code Online (Sandbox Code Playgroud)

相比于truncatedd本不会把你一个破碎的文件,如果myfile有确实没有尾随换行符。

(答案是根据评论构建,并基于此答案


Jef*_*ler 5

这是一种方法- 在文件的sed最后 ( ) 行上,搜索并用“您匹配的内容”后跟“和 Linux”替换所有内容 ( ):$.*

sed '$s/\(.*\)/\1 and Linux/' file
Run Code Online (Sandbox Code Playgroud)

由Isaac提供的一个更简单的解决方案是:

sed '$s/$/ and Linux/' file
Run Code Online (Sandbox Code Playgroud)

这会将(符号)行尾替换为给定的文本。