sponge¶
sponge
英文意思是 海绵
,有一个著名的动画 海绵宝宝 SpongeBob :
sponge
工具命令包含在 moreutils
软件包中,通常在 Ubuntu Linux 需要单独安装:
apt install moreutils
为什么叫 sponge
(海绵)呢? 原因是这个工具提供了类似 soak up
(吸干) 功能:
使用 sponge
¶
sponge
命令没有任何命令选项,唯一接受的参数是一个文件名: 例如,你可以输入 sponge newfile.txt
。
回车以后,你会看到终端等待你输入,你可以输入任意行内容,直到你按下 ctrl+d
( EOF ) 表示结束输入。
接下来,你就会在当前目录看到一个文件 newfile.txt
,内容就是你刚才在屏幕终端输入的内容。
那么,你会问,这有什么用处,我不能用 shell重定向
来实现同样的功能么?
sponge
命令 vs shell重定向
¶
sponge
命令的真正威力是结合管道 pipe
来使用
以下是一个简单
sponge
和shell重定向
案例:
echo "Put this text in a file" | sponge file1.txt
echo "Put this text in a file" > file2.txt
粗看似乎没有区别…
如果你经常编写shell,就会知道,当一个重定向( redirect
)打开一个文件写入,然后又从 stream
流读取内容到重定向管道,就会破坏文件:
$ cat cities.txt
# Cities in Pennsylvania
Philadelphia
Pittsburgh
Harrisburg
# Cities in New Jersey
Camden
Trenton
Newark
$ grep -v '^#' cities.txt
Philadelphia
Pittsburgh
Harrisburg
Camden
Trenton
Newark
可以看到 grep -v '^#'
可以过滤出文件中没有 #
注释的内容
但是,如果把上面 grep
输出到标准输出(终端)的内容再重定向到被过滤文件的自身,就会看到文件内容完全被清空了(并不是像你想象的那样去除#注释,保留正式内容):
$ grep -v '^#' cities.txt > cities.txt
grep: cities.txt: input file is also the output
$ cat cities.txt
$
所以,很多时候对上述情况,我们会采用一个中间临时文件来存储 grep
过滤中间结果,处理外后再复制回源文件:
$ grep -v '^#' cities.txt > cities.tmp
$ mv cities.tmp cities.txt
$ cat cities.txt
Philadelphia
Pittsburgh
Harrisburg
Camden
Trenton
Newark
很麻烦,不是么?
现在有请 sponge
出场:
$ grep -v '^#' cities.txt | sponge cities.txt
$ cat cities.txt
Philadelphia
Pittsburgh
Harrisburg
Camden
Trenton
Newark