Saya baru saja menjalankan yang berikut ini di bash:
uniq .bash_history > .bash_history
dan file riwayat saya akhirnya benar-benar kosong.
Saya kira saya perlu cara untuk membaca seluruh file sebelum menulis untuk itu. Bagaimana itu dilakukan?
PS: Jelas saya berpikir untuk menggunakan file sementara, tapi saya mencari solusi yang lebih elegan.
bash
tidak akan membuat dupes berurutan dalam riwayatnya jika Anda menetapkan HISTCONTROL untuk memasukkan diabaikan; lihat halaman manual.Jawaban:
Saya sarankan menggunakan
sponge
dari moreutils . Dari halaman manual:Untuk menerapkan ini pada masalah Anda, coba:
sumber
Saya hanya ingin menyumbangkan jawaban lain yang sederhana, dan tidak menggunakan spons (karena sering tidak termasuk dalam lingkungan yang ringan).
harus memiliki hasil yang diinginkan. Subshell dijalankan sebelum .bash_history dibuka untuk ditulis. Seperti dijelaskan dalam jawaban Phil P, pada saat .bash_history dibaca dalam perintah asli, sudah terpotong oleh operator '>'.
sumber
$()
bukan backticks karena beberapa masalah lolos.echo "$(fmt -p '# ' -w 50 readme.txt)" > readme.txt
hari ini. Sedang mencari-cari solusi yang elegan untuk waktu yang lama. Banyak terima kasih, @Hart Simha!Masalahnya adalah shell Anda mengatur pipeline perintah sebelum menjalankan perintah. Ini bukan masalah "input dan output", melainkan bahwa konten file sudah hilang bahkan sebelum uniq berjalan. Bunyinya seperti:
>
file output untuk menulis, memotongnyaAda berbagai solusi, termasuk pengeditan di tempat dan penggunaan file sementara yang disebutkan orang lain, tetapi kuncinya adalah untuk memahami masalahnya, apa yang sebenarnya salah dan mengapa.
sumber
Trik lain untuk melakukan ini, tanpa menggunakan
sponge
, adalah perintah berikut:Ini adalah salah satu cheat yang dijelaskan dalam artikel yang sangat baik "Di tempat" mengedit file di backreference.org.
Ini pada dasarnya membuka file untuk dibaca, kemudian "menghapusnya". Namun, itu tidak benar-benar dihapus: Ada deskriptor file terbuka yang menunjuk ke sana, dan selama itu tetap terbuka, file tersebut masih ada. Kemudian ia membuat file baru dengan nama yang sama dan menulis baris unik untuk itu.
Kerugian dari solusi ini: Jika
uniq
gagal karena alasan tertentu, riwayat Anda akan hilang.sumber
gunakan spons dari moreutils
sumber
sed
Script ini menghapus duplikat yang berdekatan. Dengan-i
opsi tersebut, ia melakukan modifikasi di tempat. Itu darised
info
file:sumber
strace
ilustrasi (bukan berarti itu penting) :-)process input > tmp && mv tmp input
jauh lebih sederhana dan lebih mudah dibaca daripada menggunakansed
tipuan hanya untuk menghindari file temp dan itu tidak akan menimpa dokumen asli saya jika gagal (saya tidak tahu jikased -i
gagal dengan anggun - saya akan pikir itu akan). Selain itu, ada banyak hal yang dapat Anda lakukan dengan metode output-ke-temp-file yang tidak dapat dilakukan di tempat tanpa sesuatu yang bahkan lebih terlibat daripadased
skrip ini . Saya tahu Anda tahu semua ini, tetapi mungkin bermanfaat bagi beberapa penonton.Sebagai berita menarik, sed juga menggunakan file temp (ini hanya berlaku untuk Anda):
Deskripsi:
Tempfile
./sedPmPv9z
menjadi fd 4, danfoo
file menjadi fd 3. Operasi baca adalah pada fd 3, dan penulisan pada fd 4 (file temp). File foo kemudian ditimpa dengan file temp di panggilan rename.sumber
Solusi lain:
sumber
File sementara cukup banyak, kecuali perintah yang dimaksud terjadi untuk mendukung pengeditan di tempat (
uniq
tidak - beberapa orangsed
melakukannya (sed -i
)).sumber
Anda dapat menggunakan Vim dalam mode Ex:
%
pilih semua garis!
jalankan perintahx
Simpan dan tutupsumber
Anda dapat menggunakan tee juga, menggunakan output uniq sebagai input:
sumber