如何在 Bash 中将文本添加到文件的开头?

use*_*534 372 bash

嗨,我想在文件中添加文本。例如,我想将任务添加到 todo.txt 文件的开头。我知道,echo 'task goes here' >> todo.txt但这将行添加到文件的末尾(不是我想要的)。

Den*_*son 477

Linux:

echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt
Run Code Online (Sandbox Code Playgroud)

或者

sed -i '1s/^/task goes here\n/' todo.txt
Run Code Online (Sandbox Code Playgroud)

或者

sed -i '1itask goes here' todo.txt
Run Code Online (Sandbox Code Playgroud)

Mac 操作系统:

sed -i '.bak' '1s/^/task goes here\'$'\n/g' todo.txt
Run Code Online (Sandbox Code Playgroud)

或者

echo -e "task goes here\n$(cat todo.txt)" > todo.txt
Run Code Online (Sandbox Code Playgroud)

或者

echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt
Run Code Online (Sandbox Code Playgroud)

  • @user8347:管道(`|`)消息(`echo '...'`)到`cat`,它使用`-`(标准输入)作为第一个文件,`todo.txt` 作为第二个文件。`cat` 连接多个文件。将输出 (`>`) 发送到名为 `temp` 的文件。如果 `cat` 没有错误(`&&`),则将 `temp` 文件重命名(`mv`)回原始文件(`todo.txt`)。 (60认同)
  • 第一个效果很好!你介意解释一下逻辑吗?我不是特别确定如何解释语法。 (8认同)
  • @Kira:`1` 表示只在文件的第一行执行下一个命令,`i` 命令是插入。查看“地址”部分下的手册页和“零或一个地址命令”部分。 (4认同)
  • 使用 2 和 3(3 对我来说似乎更简单)允许您一次将文本添加到“许多”文件中。 (2认同)

小智 91

在我看来,一个更简单的选择是:

echo -e "task goes here\n$(cat todo.txt)" > todo.txt
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为里面的命令$(...)被执行之前todo.txt被覆盖> todo.txt

虽然其他答案工作正常,但我发现这更容易记住,因为我每天都使用 echo 和 cat。

编辑:这个解决方案是一个非常糟糕的主意,如果有任何反斜杠todo.txt,因为得益于-e标志回声会解释它们。将换行符放入序言字符串的另一种更简单的方法是......

echo "task goes here
$(cat todo.txt)" > todo.txt
Run Code Online (Sandbox Code Playgroud)

...只是使用换行符。当然,它不再是单线,但实际上它以前也不是单线。如果您在脚本中执行此操作,并且担心缩进(例如,您在函数中执行此操作),则有一些解决方法可以使其仍然适合,包括但不限于:

echo 'task goes here'$'\n'"$(cat todo.txt)" > todo.txt
Run Code Online (Sandbox Code Playgroud)

另外,如果您关心是否在 末尾添加了换行符todo.txt,请不要使用这些。好吧,除了倒数第二个。这与结局无关。

  • `-e` 不会也转换 todo.txt 中的转义序列吗? (5认同)
  • 使用双引号而不是单引号可能会更好(或根本)... (2认同)
  • 变通方法 yield --> cat: <destination filename>: input file is output file ... (2认同)

slh*_*hck 33

moreutils有一个很好的工具,叫做sponge

echo "task goes here" | cat - todo.txt | sponge todo.txt
Run Code Online (Sandbox Code Playgroud)

它会“吸收”STDIN,然后写入文件,这意味着您不必担心临时文件和移动它们。

您可以moreutils通过apt-get install moreutils或在 OS X 上使用Homebrewbrew install moreutils.


Ste*_*nny 16

您可以使用 POSIX 工具ex

ex a.txt <<eof
1 insert
Sunday
.
xit
eof
Run Code Online (Sandbox Code Playgroud)

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html


Kei*_*ith 5

您可以创建一个新的临时文件。

echo "new task" > new_todo.txt
cat todo.txt >> new_todo.txt
rm todo.txt
mv new_todo.txt todo.txt
Run Code Online (Sandbox Code Playgroud)

您也可以使用sedawk。但基本上会发生同样的事情。

  • 假设您的磁盘空间不足,因此“new_todo.txt”只能部分写入。您的解决方案似乎丢失了原始文件。 (2认同)
  • @Keith 在 VM 上工作的人并不期望需要一个特别大的虚拟驱动器。或者有人移动一个大文件。无论如何,反对这一点的真正理由是目录权限;如果您无权在给定目录中创建新文件,则脚本中唯一能成功执行的命令是原始文件的“rm”。 (2认同)

Ruc*_*t88 5

如果文本文件足够小,可以容纳在内存中,则无需创建临时文件来替换它。您可以将其全部加载到内存中并将其写回到文件中。

echo "$(echo 'task goes here' | cat - todo.txt)" > todo.txt
Run Code Online (Sandbox Code Playgroud)

不可能在不覆盖整个文件的情况下将行添加到文件的开头。