在 Bash 中,向文件追加文本意味着将内容添加到文件末尾,而不覆盖已有的内容。>> 重定向运算符是最直接的方法,但 tee 命令和 heredoc 语法提供了额外的灵活性,尤其是在需要追加到多个文件或需要提升权限的文件时。

要追加到文件,您需要对该文件具有写权限。否则,您将收到 Permission denied 错误。

本指南通过每种方法的实用示例,讲解如何在 Bash 中向文件追加内容。

快速参考

如需可打印的快速参考,请参阅 Bash 速查表。

方法命令适用场景
重定向echo "text" >> file.txt追加到单个文件
重定向 + 错误command >> file.txt 2>&1追加输出和错误消息
Heredoccat << EOF >> file.txt追加多行内容
teeecho "text" | tee -a file.txt追加并显示输出
tee + sudoecho "text" | sudo tee -a file.txt追加到受保护的文件
tee 多个文件echo "text" | tee -a f1.txt f2.txt同时追加到多个文件
追加一个文件cat source.txt >> target.txt将一个文件的内容添加到另一个文件

使用重定向追加到文件

重定向允许您捕获命令的输出并将其发送到文件。>> 运算符将输出追加到文件末尾,而不会覆盖现有内容。

用于将文本打印到标准输出的两个最常用命令是 echo 和 printf。要将它们的输出追加到文件,请在 >> 运算符后指定文件名:

终端
echo "this is a new line" >> file.txt

终端上不会显示任何内容,因为输出已写入文件。假设 file.txt 原本包含一行内容,可以显示它来查看结果:

终端
cat file.txt
输出
an existing line
this is a new line

原始内容保持不变,新文本位于其下方。这就是 >> 和 > 之间的全部区别。

当与 -e 选项一起使用时,echo 命令会解释反斜杠转义字符,例如表示换行的 \n:

终端
echo -e "this is a new line \nthis is another new line" >> file.txt

每个 \n 都会开始一个新行,因此这条命令会追加两行而不是一行。

要生成更复杂或格式化的输出,请使用 printf 命令:

终端
printf "Hello, I am %s.\n" "$USER" >> file.txt

%s 占位符会被替换为 $USER 的值,末尾的 \n 用于结束该行。与 echo 不同,printf 从不自行添加换行符,因此省略 \n 会使文本与文件最后一行已有的内容连在一起。

您可以将任何命令的输出追加到文件中。以下是使用 date 命令的示例:

终端
date +"Year: %Y, Month: %m, Day: %d" >> file.txt

使用 >> 的重定向仅捕获标准输出。当命令也可能失败时,请在重定向后添加 2>&1,以将其错误消息追加到同一文件中:

终端
find /etc -name "*.conf" >> results.txt 2>&1

Bash 4 及更高版本还支持更简短的 &>> 形式,它可以使用单个运算符追加两个流:

终端
find /etc -name "*.conf" &>> results.txt

在第一种形式中,顺序很重要。2>&1 必须放在 >> results.txt 之后。如果放在前面,标准错误仍会连接到文件重定向之前标准输出所指向的位置,通常是终端。我们的《重定向 stderr 和 stdout》指南解释了原因。

要一次追加多行,请使用 Here document(heredoc)。这是一种将文本块作为输入传递给命令的重定向类型。以下示例将内容传递给 cat 命令并将其追加到文件中:

sh
cat << EOF >> file.txt
The current working directory is: $PWD
You are logged in as: $(whoami)
EOF

$PWD 和 $(whoami) 都会在文本写入之前被展开,因此文件接收的是解析后的值,而不是字面变量名。使用 tail 显示追加的两行:

终端
tail -n 2 file.txt
输出
The current working directory is: /home/linuxize
You are logged in as: linuxize

输出显示了存储在文件中的展开后的工作目录和用户名。

使用重定向追加到文件时,请始终使用 >>。使用单个 > 运算符会覆盖整个文件,而不是追加内容。

使用 tee 追加到文件

tee 命令从标准输入读取,并同时写入标准输出和一个或多个文件。

默认情况下,tee 会覆盖指定的文件。若要改为追加,请使用 -a(--append)选项:

终端
echo "this is a new line" | tee -a file.txt
输出
this is a new line

与 >> 不同,tee 会回显它写入的所有内容,因此文本会同时出现在终端上和文件末尾。这使其非常适合那些希望日志条目既被保存又被立即显示的脚本。

如果您不希望 tee 写入标准输出,请将其重定向到 /dev/null:

终端
echo "this is a new line" | tee -a file.txt >/dev/null

tee 相对于 >> 的一个优势是它可以与 sudo 配合使用,从而允许您追加到由 root 或其他用户拥有的文件。与 sudo 结合使用时,tee 以提升的权限运行,并且可以写入受保护的文件:

终端
echo "this is a new line" | sudo tee -a file.txt

要一次追加到多个文件,请将多个文件名作为参数传递:

终端
echo "this is a new line" | tee -a file1.txt file2.txt file3.txt

使用 cat 将一个文件追加到另一个文件

一项常见任务是将一个文件的内容添加到另一个文件的末尾。使用 >> 运算符重定向 cat 的输出:

终端
cat source.txt >> target.txt

这会读取 source.txt 并将每一行追加到 target.txt,同时保留目标文件的原始内容。要将多个文件合并为一个,请在运算符之前列出所有文件:

终端
cat file1.txt file2.txt >> combined.txt

cat 按给定顺序连接这些文件,并将结果追加到 combined.txt。

如果 target.txt 包含一行,而 source.txt 包含两行,则合并后的文件如下所示:

终端
cat target.txt
输出
existing line
line one
line two

在文件开头插入文本

追加会将文本放在文件末尾。相反的操作——前置(prepend)——则将文本放在文件顶部。重定向本身无法做到这一点,因为 >> 总是写入末尾。

对于非空文件,GNU sed 可以在第 1 行之前插入文本。在不更改文件的情况下预览结果:

终端
sed '1i this is the first line' file.txt

如果预览正确,请使用 -i.bak 编辑文件,并将原始文件保留为 file.txt.bak:

终端
sed -i.bak '1i this is the first line' file.txt

显示编辑后的文件以确认新行位于顶部:

终端
cat file.txt
输出
this is the first line
an existing line
this is a new line

备份保留了先前的文件内容和权限,以便您在需要时进行恢复。

故障排除

文件内容被覆盖而不是被追加
您使用了 > 而不是 >>。单个 > 运算符会在写入前截断文件。请始终使用 >> 以保留现有内容。

追加时出现 Permission denied
您的用户没有该文件的写权限。请使用 sudo tee -a 代替 >>:echo "text" | sudo tee -a file.txt。

使用 >> 重定向后,终端上仍然出现错误
>> 运算符仅重定向标准输出。请在重定向后添加 2>&1,例如 command >> file.txt 2>&1,以将错误消息发送到同一文件。

Heredoc 内容出现意外的缩进
Heredoc 正文内的制表符会在输出中按原样保留。请使用 <<-EOF 代替 <<EOF,以去除每行开头的制表符。

常见问题解答

> 和 >> 有什么区别?
> 会从文件开头覆盖写入,破坏所有现有内容。>> 会追加到文件末尾,并保持现有内容不变。在重定向到重要文件之前,请务必仔细检查所使用的运算符。

如何向文件中追加一个空行?
运行 echo >> file.txt。不带参数时,echo 会输出一个空行,而 >> 会将该空行追加到文件中。

如何在 Bash 脚本中向文件追加内容?
在脚本中使用相同的 >> 运算符或 tee -a。本指南中的所有方法在脚本中的工作方式完全相同。

如何向没有写入权限的文件追加内容?
结合 sudo 将输出通过管道传递给 tee -a:echo "text" | sudo tee -a /etc/file.conf。这将以 root 身份运行 tee,同时保持您自己的 shell 会话为非特权状态。

如何在不添加换行符的情况下追加文本?
使用不带尾部 \n 的 printf,例如 printf 'text' >> file.txt。除非传入 -n 选项,否则 echo 命令始终会在输出末尾添加换行符。

如何将一行添加到文件的开头而不是末尾?
在 Linux 上,使用 sed '1i your text' file.txt 预览更改,然后使用 sed -i.bak '1i your text' file.txt 应用更改。>> 运算符只能写入文件末尾,因此在开头插入内容需要重写整个文件。