spons dari moreutils - apa bedanya dengan shell redirect? contoh berguna?

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

spons membaca input standar dan menuliskannya ke file yang ditentukan. Tidak seperti pengalihan shell, spons menyerap semua inputnya sebelum menulis file output. Ini memungkinkan membangun saluran pipa yang membaca dari dan menulis ke file yang sama.

Saya tidak mengerti. Tolong beri saya beberapa contoh berguna.

Apa artinya menyerap ?

Ivanov
sumber
1
unix.stackexchange.com/search?q=sponge
Gilles 'SO- stop being evil'
Contoh lain adalah expand foo.txt | sponge foo.txt. Lihat juga: stackoverflow.com/a/33639324/1959808
Ioannis Filippidis

Jawaban:

32

Asumsikan bahwa Anda memiliki file bernama input, Anda ingin menghapus semua baris mulai dengan #di input. Anda bisa mendapatkan semua baris jangan mulai dengan #menggunakan:

grep -v '^#' input

Tapi bagaimana Anda membuat perubahan input? Dengan toolchest POSIX standar, Anda perlu menggunakan file sementara, beberapa hal seperti:

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

Dengan pengalihan shell:

grep -v '^#' input >input

akan terpotong inputsebelum Anda membacanya.

Dengan sponge, Anda dapat:

grep -v '^#' input | sponge input
cuonglm
sumber
4
Anda sebenarnya dapat membaca dan menulis file pada saat yang sama dengan aman selama byte hanya ditransformasikan, menggunakan <>operator.
Chris Down
@ ChrisDown: Ya, maksud saya tanpa membuatnya corroupt
cuonglm
Saya tidak yakin apa yang Anda maksud dengan "membuatnya korup". Berbeda >dan <, <>tidak merusak file kecuali ada yang salah. Anda dapat dengan mudah menulis byte demi byte menggunakannya. Misalnya, coba gunakan dengan tr.
Chris Down
@ChrisDown: Biarkan saya menghapus kalimat itu untuk menghindari kebingungan. Maksud saya sebenarnya ketika menggunakan <>file, Anda membuka file untuk membaca dan menulis tetapi Anda sebenarnya tidak menulis apa pun ke file.
cuonglm
1
Saya pikir poin yang @ChrisDown coba lakukan adalah <>tidak memotong file, tetapi hanya mengganti byte yang ada dengan output baru. Jika output baru terlalu pendek, Anda akan memiliki sisa sampah di akhir file. Tetapi jika output baru cukup lama, tidak ada risiko.
BallpointBen
7

Halaman muka moreutils sendiri mendokumentasikan kasus penggunaan umum:

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

Di sini, / etc / passwd ditulis dan dibaca, dan sedang dimodifikasi. Tanpa melonggarkan stdin sebelum menulis, / etc / passwd mungkin rusak (karena file berubah saat membaca).

Chris Down
sumber
Dan itu akan menjadi contoh yang baik pada halaman moreutils, jika itu menjelaskan cara Anda melakukannya :-)
Br.Bill