Saya memiliki file temp.txt, yang ingin saya sortir dengan sort
perintah di bash.
Saya ingin hasil yang diurutkan menggantikan file asli.
Ini tidak berfungsi misalnya (saya mendapatkan file kosong):
sortx temp.txt > temp.txt
Bisakah ini dilakukan dalam satu baris tanpa harus menyalin ke file sementara?
EDIT: -o
Opsinya sangat keren sort
. Saya menggunakan sort
pertanyaan saya sebagai contoh. Saya mengalami masalah yang sama dengan perintah lain:
uniq temp.txt > temp.txt.
Apakah ada solusi umum yang lebih baik?
Jawaban:
sumber
sort --inplace *.txt
? Itu akan sangat kerenfind . -name \*.txt -exec sort {} -o {} \;
A
sort
perlu melihat semua masukan sebelum dapat mulai menghasilkan. Karena alasan ini,sort
program dapat dengan mudah menawarkan opsi untuk mengubah file di tempat:Secara khusus, dokumentasi GNU
sort
mengatakan:Sedangkan dokumentasi BSD
sort
menyebutkan:Perintah seperti
uniq
dapat mulai menulis keluaran sebelum selesai membaca masukan. Perintah ini biasanya tidak mendukung pengeditan di tempat (dan akan lebih sulit bagi mereka untuk mendukung fitur ini).Anda biasanya mengatasinya dengan file sementara, atau jika Anda benar-benar ingin menghindari file perantara, Anda dapat menggunakan buffer untuk menyimpan hasil lengkap sebelum menulisnya. Misalnya dengan
perl
:Di sini, bagian perl membaca keluaran lengkap dari
uniq
dalam variabel$_
dan kemudian menimpa file asli dengan data ini. Anda dapat melakukan hal yang sama dalam bahasa skrip pilihan Anda, bahkan mungkin di Bash. Tetapi perhatikan bahwa itu akan membutuhkan cukup memori untuk menyimpan seluruh file, ini tidak disarankan saat bekerja dengan file besar.sumber
Berikut pendekatan yang lebih umum, bekerja dengan uniq, sort dan yang lainnya.
sumber
sponge
dari MoreUtils:cat file |frobnicate |sponge file
.Komentar Tobu tentang jaminan spons menjadi jawaban tersendiri.
Mengutip dari beranda moreutils :
Namun, Steve Jessop
sponge
menderita masalah yang sama dengan komentar di sini. Jika salah satu perintah dalam pipeline sebelumnyasponge
gagal, maka file asli akan diganti.Uh-oh,
my-important-file
hilang.sumber
set -o pipefail
di awal skrip Anda, kesalahan padamistyped_command my-important-file
akan membuat skrip segera keluar, sebelum dijalankansponge
, sehingga menjaga file penting.Ini dia, satu baris:
Secara teknis tidak ada penyalinan ke file sementara, dan perintah 'mv' harus instan.
sumber
Saya suka
sort file -o file
jawabannya tetapi tidak ingin mengetik nama file yang sama dua kali.Menggunakan ekspansi riwayat BASH :
mengambil argumen pertama baris saat ini saat Anda menekan enter.
Urutan unik di tempat:
mengambil argumen terakhir di baris saat ini.
sumber
Banyak yang menyebutkan opsi -o . Ini adalah bagian halaman manual.
Dari halaman manual:
sumber
Ini akan sangat membatasi memori, tetapi Anda dapat menggunakan awk untuk menyimpan data perantara dalam memori, dan kemudian menuliskannya kembali.
sumber
>
memotong file sebelum perintah (uniq
dalam hal ini) membacanya.Alternatif
sponge
dengan yang lebih umumsed
:Ia bekerja untuk perintah apapun (
sort
,uniq
,tac
, ...) dan penggunaan yang sangat terkenalsed
's-i
pilihan (mengedit file di tempat).Peringatan: Coba
command file
dulu karena mengedit file di tempat pada dasarnya tidak aman.Penjelasan
Pertama, Anda mengatakan
sed
tidak untuk mencetak (asli) baris (-n
option ), dan dengan bantuan darised
'sr
perintah danbash
' s Proses Pergantian , konten yang dihasilkan oleh<(command file)
akan menjadi output disimpan di tempat .Membuat segalanya lebih mudah
Anda dapat menggabungkan solusi ini menjadi sebuah fungsi:
Contoh
sumber
Gunakan argumen
--output=
atau-o
Baru saja mencoba FreeBSD:
sumber
Untuk menambah
uniq
kemampuan, apa kerugiannya:sumber
Baca di editor non-interaktif
ex
,.sumber
Jika Anda bersikeras menggunakan
sort
program ini, Anda harus menggunakan file perantara - saya rasa tidaksort
memiliki opsi untuk menyortir dalam memori. Trik lain dengan stdin / stdout akan gagal kecuali Anda dapat menjamin bahwa ukuran buffer untuk stdin sort cukup besar untuk memuat seluruh file.Sunting: malu padaku.
sort temp.txt -o temp.txt
bekerja dengan sangat baik.sumber
Solusi lain:
sumber
<>
trik hanya berfungsi dalam kasus ini karenauniq
khusus karena hanya menyalin jalur input ke jalur output, menjatuhkan beberapa di jalan. Jika perintah lain (misalnyased
) digunakan yang akan mengubah masukan (misalnya akan mengubah setiapa
menjadiaa
), maka perintah tersebut dapat menimpafile
dengan cara yang tidak masuk akal dan bahkan berulang tanpa batas, asalkan masukan cukup besar (lebih dari satu buffer baca tunggal).