覆盖输入文件

覆盖输入文件

我遇到的用转换后的输出替换输入文件内容的解决方案涉及使用临时文件或海绵公用事业。

斯蒂芬·查泽拉斯 回答这里表示另一种以读写模式打开文件的方法,如下所示。

tr ' ' '\t' < file 1<> file

在不损坏相关文件的情况下,这实际上是如何工作的?

答案1

这只有效,因为tr不会更改文件大小。

1<>filefile在覆盖模式下作为标准输出打开。 (<>称为读/写模式,但由于很少有程序读取stdout,因此关注它实际执行的操作更有用。)

通常,当您重定向输出 ( >file) 时,文件会以“写入”模式打开,这会导致文件被创建或清空。另一个常见的选项是>>file“追加”模式,它会跳过清空文件的步骤,但将所有输出放在最后。1<>file也会跳过清空文件,但它将写入光标放在文件的开头。 (您需要1因为<>默认为重定向stdin,而不是stdout)。

这只是偶尔有用,因为很少有实用程序的修改如此精确。另一种情况是搜索和替换,其中替换的长度与原始长度完全相同。 (较短的替换也不起作用,因为文件在末尾不会被截断;如果输出比原始文件短,那么最终文件末尾的内容仍然在末尾文件的。)

答案2

当您使用以只读方式打开文件的语法< file并将文件中的行内容读入标准输入(STDIN 又名文件描述符 0)时。然后,标准输出(STDOUT 又名文件描述符 1)以读+写(1<>)的方式打开,并且各行的内容因此被写出。

您可以在本节中阅读有关 I/O + Bash 的更多信息,第 20 章 I/O 重定向,《高级 Bash 脚本指南》。

摘抄

   [j]<>filename
      #  Open file "filename" for reading and writing,
      #+ and assign file descriptor "j" to it.
      #  If "filename" does not exist, create it.
      #  If file descriptor "j" is not specified, default to fd 0, stdin.
      #
      #  An application of this is writing at a specified place in a file. 
      echo 1234567890 > File    # Write string to "File".
      exec 3<> File             # Open "File" and assign fd 3 to it.
      read -n 4 <&3             # Read only 4 characters.
      echo -n . >&3             # Write a decimal point there.
      exec 3>&-                 # Close fd 3.
      cat File                  # ==> 1234.67890
      #  Random access, by golly.

同一个文件多次打开,怎么办?

在这个 U&L 问答中看看文件描述符是如何工作的:不同进程中的同一个fd如何指向同一个文件?。它涵盖了如何多次打开同一文件。

相关内容