如果文件已存在,写入文件时覆盖原文件

396
echo "text" >> 'Users/Name/Desktop/TheAccount.txt'

如何在文件不存在的情况下创建文件,但如果已经存在则覆盖它。目前这个脚本只能追加内容。

9个回答

616

>> 重定向操作符会将行追加到指定文件的末尾,而单个大于号 > 则会清空并覆盖文件。

echo "text" > 'Users/Name/Desktop/TheAccount.txt'

22
有些环境会禁止操作,比如会出现"-bash: TheAccount.txt: cannot overwrite existing file"这样的提示。 - Tom Russell
60
好的,请提供需要翻译的内容。 - Jake
它在Ubuntu 20.10上使用bash 5工作。 - user3064538
跟这个话题有点相关的问题是,学习bash的小技巧最好的方法是什么?我之前不知道这个答案,但它非常有帮助。我发现很难在“全面阅读bash参考手册”和“在Stackoverflow上搜索每个问题”之间找到一个折中的方法。 - Urthor
1
这个答案并没有直接回答问题。正如Jake所指出的,@BrDaHa的回答已经回答了它。 - macetw

158
在Bash中,如果你已经设置了noclobber,比如使用set -o noclobber命令,那么你可以使用语法>|。例如:
echo "some text" >| existing_file

如果文件不存在,这也适用。


  • 使用set -o | grep noclobber检查是否已设置noclobber。

  • 有关此特殊类型的运算符的更详细说明,请参见此帖子

  • 有关重定向运算符的更全面列表,请参见此帖子


@BrDaHa 我怎样才能使用 >| 一起重定向 stderr?我尝试了 &>| 但是它没有起作用。 - Tu Bui
@Griddo 我的shell是bash版本4.3.48(1)-release。echo "aaa" &>| test.txt会出现错误-bash: syntax error near unexpected token |。我的noclobber已经开启。 - Tu Bui
2
@TuBui 看来我测试的不正确。它对我也不起作用...然而文档也没有说明应该是可能的。你可能必须坚持使用 echo "aaa" >| test.txt 2>&1 或者使用另一个 shell。 - Gerrit-K
">!" 对我也很好用(参见:http://linuxhowtos.org/Tips%20and%20Tricks/Protecting%20files%20with%20noclobber.htm)" - CyberMew
@CyberMew 因为你正在使用 zsh - BrDaHa
显示剩余2条评论

40

尽管NylonSmile的答案“有点”正确,但我无法以这种方式覆盖文件。

echo "我知道管道,女友" > thatAnswer

zsh:文件已存在:thatAnswer

为了解决我的问题,我必须使用>! á la ..

[[ $FORCE_IT == 'YES' ]] && echo "$@" >! "$X" || echo "$@" > "$X"

显然,你要小心处理这个...


29
这意味着你设置了非默认的zsh选项NOCLOBBER。使用setopt clobber恢复默认行为即可。 - Michał Politowski

24

如果你的环境不允许使用>覆盖,请使用管道符|tee代替,方法如下:

echo "text" | tee 'Users/Name/Desktop/TheAccount.txt'

请注意,这也会打印到标准输出。如果不希望这样,请按以下方式将输出重定向到/dev/null

echo "text" | tee 'Users/Name/Desktop/TheAccount.txt' > /dev/null

3
这是我唯一行之有效的解决方案。 - shellcat_zero

6
#!/bin/bash

cat <<EOF > SampleFile

Put Some text here 
Put some text here
Put some text here

EOF

无法覆盖现有文件。 - madduci
在我的情况下可行。如果文件不存在则创建新文件,如果文件已经存在则覆盖。 - SRi

4

请注意,如果您想在设置了noclobber(即set -o noclobber)的情况下将stderr和stdout都重定向到文件中,您可以使用以下代码:

cmd >| file.txt 2>&1

更多信息可以在 https://dev59.com/enNA5IYBdhLWcg3wpvtg#876242 查看。
此外,这个答案回答了 @TuBui 在答案 @BrDaHa 提供的 上面 关于 18 年 8 月 9 日 9:34 的问题。

1

如果要将一个文件的内容覆盖到另一个文件中,可以使用单个大于号,使用两个大于号则会追加。

echo  "this is foo" > foobar.txt
cat foobar.txt
    > this is foo

echo "this is bar" > foobar.txt
cat foobar.txt
    > this is bar
    

echo "this is foo, again" >> foobar.txt
cat foobar.txt
    > this is bar
    > this is foo, again
    

正如其他答案中提到的那样,如果你设置了noclobber,那么请使用>|运算符。


3
现在要覆盖foobar...">>符号表示追加而非覆盖。 - Drenai

0
如果文本是命令的输出,比如ls,你可以使用cat
当noclobber被设置时:
ls | cat>| TheAccount.txt

否则,您可以结合强制删除(无论文件是否存在)和ls命令:
file=TheAccount.txt && rm -f $file && ls | cat > $file

-4
如果您的输出可能会出现错误,您可能希望使用一个“&”符号和一个大于号,如下所示: my_task &> 'Users/Name/Desktop/task_output.log' 这将把stderr和stdout都重定向到日志文件中(而不仅仅是stdout)。

6
可能是正确的,但与问题无关。 - Deiwin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接