来自 moreutils 的海绵 - shell 重定向有什么区别?有用的例子?

Jos*_*ine 26 command-line shell io-redirection utilities

> brew install moreutils                                                          
==> Downloading https://homebrew.bintray.com/bottles/moreutils-0.55.yosemite.bottle.tar.gz    
######################################################################## 100.0%               
==> Pouring moreutils0.55.yosemite.bottle.tar.gz       
  /usr/local/Cellar/moreutils/0.55: 67 files, 740K   
Run Code Online (Sandbox Code Playgroud)

海绵读取标准输入并将其写出到指定的文件。与 shell 重定向不同,海绵在写入输出文件之前吸收所有输入。这允许构建读取和写入同一文件的管道。

我不明白。请给我一些有用的例子。

什么吸收了是什么意思?

cuo*_*glm 41

假设您有一个名为 的文件input,您想删除所有以#in开头的行input。您可以获得所有行不以#使用开头:

grep -v '^#' input
Run Code Online (Sandbox Code Playgroud)

但是你如何改变input?使用标准的 POSIX 工具箱,您需要使用一个临时文件,例如:

grep -v '^#' input >/tmp/input.tmp
mv /tmp/input.tmp ./input
Run Code Online (Sandbox Code Playgroud)

使用外壳重定向:

grep -v '^#' input >input
Run Code Online (Sandbox Code Playgroud)

input在您阅读它之前将被截断。

使用sponge,您可以:

grep -v '^#' input | sponge input
Run Code Online (Sandbox Code Playgroud)

  • 您实际上可以安全地同时读取和写入文件,只要字节仅被转换,使用 `<>` 运算符。 (5认同)
  • 我认为@ChrisDown 试图提出的观点是`<>` 不会截断文件,而只是用新输出替换其现有字节。如果新的输出太短,文件末尾就会有剩余的垃圾。但如果新的输出足够长,就没有风险。 (4认同)

Chr*_*own 15

moreutils主页本身记录了典型的用例:

sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd
Run Code Online (Sandbox Code Playgroud)

这里,/etc/passwd 正在被写入和读取,并且正在被修改。如果在写入之前不使用标准输入,/etc/passwd 可能会损坏(因为文件在读取过程中发生了变化)。

  • 这将是 moreutils 页面上的一个很好的例子,如果它解释了你的方式:-) (2认同)