11
> 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   

sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before writing the output file. This allows constructing pipelines that read from and write to the same file.

I don't understand. Please give me some useful examples.

What does soaks up mean?

26

Assume that you have a file named input, you want to remove all line start with # in input. You can get all lines don't start with # using:

grep -v '^#' input

But how do you make changes to input? With standard POSIX toolchest, you need to use a temporary file, some thing like:

grep -v '^#' input >/tmp/input.tmp
mv /tmp/input.tmp ./input

With shell redirection:

grep -v '^#' input >input

will truncate input before you reading from it.

With sponge, you can:

grep -v '^#' input | sponge input
  • 3
    You actually can read and write a file at the same time safely as long as the bytes are only being transformed, using the <> operator. – Chris Down Jun 6 '15 at 9:14
  • @ChrisDown: Yes, I mean without making it corroupt – cuonglm Jun 6 '15 at 9:19
  • I'm not sure what you mean about "making it corrupt". Unlike > and <, <> doesn't corrupt the file unless something went really wrong. You can quite easily write byte by byte using it. For example, try using it with tr. – Chris Down Jun 6 '15 at 20:01
  • @ChrisDown: Let me remove that sentence to avoid confusing. I actually mean when using <>file, you open file for reading and writing but you actually don't write anything to file. – cuonglm Jun 7 '15 at 7:12
  • Did you try it? :-) <> has no problem writing to a file, try it for yourself: printf foobar >q; printf bar 1<>q results in barbar. – Chris Down Jun 7 '15 at 7:46
5

The moreutils home page itself documents a typical use case:

sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd

Here, /etc/passwd is both being written to and read to, and is being modified. Without sponging up stdin before writing, /etc/passwd might be corrupted (as the file changed during reading).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.