如何重定向而不擦除文件cat myfile> MYFILE

时间:2014-01-31 23:47:44

标签: bash

我有一个问题是在没有删除文件的情况下重定向到文件的正确方法是什么? 我正在使用bash。我想做点什么:

cat myfile > myfile

程序(即cat)读取文件然后重定向到文件,因此在上面的示例中,“myfile”将保持不变。

我知道上面的例子会删除文件as explained here

什么是正确的语法,以便文件不会被删除?是否可以进行stdout和重定向,或者程序是否应该处理打开并将新数据写入文件?我想让我的程序只输出到stdout,然后用户可以重定向或管道或其他任何东西。

BTW,我不想>>并连接。我希望左边的函数将“新”数据写入文件。

或许更好的说明方式是我希望重定向的左侧在流式传输发生之前完全发生,这可能吗?如果我对bash有一个基本的误解,请赐教: - )

3 个答案:

答案 0 :(得分:2)

您必须先将所有数据读入内存,或者写入临时文件并将其交换出来。

要将其读入内存(例如vimed和其他编辑者):

contents=$(<myfile)
cat <<< "$contents" > myfile

要创建临时文件(例如sed -irsync和其他更新工具,请执行以下操作):

tmpfile=$(mktemp fooXXXXXX)
cat myfile > "$tmpfile" && mv "$tmpfile" myfile

答案 1 :(得分:1)

据推测,你有兴趣做一些比cat myfile更复杂的事情。

某些命令具有允许您执行此操作的命令行参数(通常为-i) - 但这些选项通过写入临时文件然后重命名临时文件来工作。

你可以自己做同样的事情:

cat myfile > myfile.$$ && mv myfile.$$ myfile

我经常使用$$扩展为我的shell的进程ID,作为临时文件的后缀;它使名称不太可能与其他文件冲突。

使用&&意味着除非cat命令成功,否则它不会破坏您的输入文件。

此方法的一个可能问题是您的新文件myfile.$$是新创建的文件,因此它不会保留原始输入文件的权限。如果你有chmod命令的GNU Coreutils版本,你可以避免这个问题:

cat myfile > myfile.$$ && \
    chmod --reference=myfile myfile.$$ && \
    mv myfile.$$ myfile

答案 2 :(得分:0)

我在这里按字面意思提问。通过引入管道来读取cat的输出,第二个管道进程从stdin读取输出并将其重定向到原始文件名,从而有效地生成未更改的文件。

cat myfile | cat - > myfile