Saya telah menemukan pertanyaan (pada SO itu sendiri) di mana OP harus melakukan edit dan menyimpan operasi ke Input_file itu sendiri.
Saya tahu untuk satu Input_file yang bisa kami lakukan sebagai berikut:
awk '{print "test here..new line for saving.."}' Input_file > temp && mv temp Input_file
Sekarang katakanlah kita perlu membuat perubahan dalam format file yang sama (asumsikan .txt di sini).
Apa yang saya coba / pikirkan untuk masalah ini: Pendekatannya adalah melalui loop untuk file .txt dan memanggil tunggalawk
adalah proses yang menyakitkan dan TIDAK direkomendasikan, karena akan membuang siklus cpu yang tidak perlu dan untuk lebih banyak jumlah file akan lebih lambat.
Jadi apa yang mungkin bisa dilakukan di sini untuk melakukan inplace edit untuk banyak file dengan NON GNU awk
yang tidak mendukung opsi inplace. Saya juga telah melalui utas ini. Simpan modifikasi di tempat dengan awk tetapi tidak ada banyak untuk wakil NON GNU awk dan mengubah beberapa file di dalamawk
dirinya sendiri, karena awk non GNU tidak akan memiliki inplace
pilihan untuk itu.
CATATAN: Mengapa saya menambahkanbash
tag sejak itu, di bagian jawaban saya, saya telah menggunakan perintah bash untuk mengganti nama file sementara ke nama Input_file mereka yang sebenarnya sehingga menambahkannya.
EDIT: Sesuai komentar Ed sir menambahkan contoh sampel di sini, meskipun tujuan dari kode utas ini dapat digunakan oleh mengedit inplace tujuan umum juga.
Sampel Input_file:
cat test1.txt
onetwo three
tets testtest
cat test2.txt
onetwo three
tets testtest
cat test3.txt
onetwo three
tets testtest
Contoh output yang diharapkan:
cat test1.txt
1
2
cat test2.txt
1
2
cat test3.txt
1
2
awk
, (mungkin dalam subkulit) atau{...}
grup terlampir dan kemudian menulis hasilnya ke file output yang diinginkan (baik untuk setiap file input, atau file gabungan untuk semua file input). Kemudian Anda cukup mengarahkan output dari subkulit atau kelompok kurung kurawal ke file saat ini yang sedang ditulis? Cukup dengan memasukkan serangkaian file input setelahawk
perintah akan memproses semua file secara berurutan (atau yang serupa) ??awk {..} file1 .. fileX
menulis file yang dimodifikasi sebagai, misalnyatemp01
dan dalam iterasi Anda berikutnya saat memproses file berikutnya, gunakan amv -f tmp01 input01
untuk menimpa file input dengan data yang dimodifikasi; atau (2) cukup menulis direktori baru./tmp/tmp01 ... ./tmp/tmp0X
selama eksekusiawk
skrip dan menindaklanjutinya dengan loop atas file dalam./tmp
direktori dan, misalnyamv -f "$i" "input_${i##*[^0-9]}"
(atau ekspansi apa pun yang Anda perlukan untuk mengganti file input lama.awk
penyelesaian kode lengkap, opsi ke-2 hampir sama dengan apa yang saya gunakan dalam saran saya, akan bersyukurlah jika Anda bisa memberi tahu pikiran Anda tentang solusi itu, Pak.Jawaban:
Karena tujuan utama dari utas ini adalah bagaimana melakukan inplace SIMPAN di NON GNU
awk
jadi saya memposting templatnya terlebih dahulu yang akan membantu siapa pun dalam segala jenis persyaratan, mereka perlu menambahkan / menambahkanBEGIN
danEND
bagian dalam kode mereka menjaga BLOCK utama mereka sesuai persyaratan dan harus melakukan inplace edit kemudian:CATATAN: Mengikuti akan menulis semua outputnya ke output_file, jadi jika Anda ingin mencetak apa pun ke output standar, harap hanya menambahkan
print...
pernyataan tanpa> (out)
mengikuti.Templat Generik:
Solusi sampel khusus yang disediakan:
Saya telah datang dengan pendekatan berikut dalam
awk
dirinya sendiri (untuk sampel tambahan berikut adalah pendekatan saya untuk menyelesaikan ini dan menyimpan output ke Input_file itu sendiri)CATATAN: ini hanya tes untuk menyimpan output yang diedit ke dalam Input_file itu sendiri, orang dapat menggunakan bagian BEGIN-nya, bersama dengan bagian END-nya dalam program mereka, bagian utama harus sesuai dengan persyaratan pertanyaan spesifik itu sendiri.
Peringatan yang adil: Juga karena pendekatan ini membuat file sementara sementara baru di jalur jadi lebih baik pastikan kita memiliki cukup ruang pada sistem, meskipun pada hasil akhir ini hanya akan menyimpan Input_file utama tetapi selama operasi itu membutuhkan ruang pada sistem / direktori
Berikut ini adalah tes untuk kode di atas.
Eksekusi program dengan contoh: Mari kita asumsikan berikut ini adalah
.txt
Input_file:Sekarang ketika kita menjalankan kode berikut:
CATATAN: Saya memiliki tempat
ls -lhtr
disystem
bagian yang sengaja untuk melihat file output mana yang sedang dibuat (sementara) karena nanti akan mengubah nama mereka menjadi nama sebenarnya.Ketika kita melakukan skrip
ls -lhtr
setelahawk
selesai menjalankan, kita hanya bisa melihat.txt
file di sana.Penjelasan: Menambahkan penjelasan rinci tentang perintah di atas di sini:
sumber
FNR==1
blokir, Anda masih dapat menyimpan perubahan di tempat. Sepertiawk 'FNR==1{system("rm " FILENAME)} {print "new lines" > FILENAME}' files...
. Ini sama sekali tidak dapat diandalkan (kehilangan data lengkap kemungkinan akan terjadi), tetapi tetap saja, sebagian besar berfungsi dengan baik: DSaya mungkin akan pergi dengan sesuatu seperti ini jika saya mencoba melakukan ini:
Saya lebih suka menyalin file asli ke cadangan terlebih dahulu dan kemudian beroperasi pada perubahan penyimpanan ke yang asli tetapi melakukan itu akan mengubah nilai variabel FILENAME untuk setiap file input yang tidak diinginkan.
Perhatikan bahwa jika Anda memiliki file asli bernama
whatever.bak
atauwhatever.new
di direktori Anda maka Anda akan menimpanya dengan file temp sehingga Anda perlu menambahkan tes untuk itu juga. Panggilan kemktemp
mendapatkan nama file temp akan lebih kuat.JAUH lebih berguna untuk dimiliki dalam situasi ini akan menjadi alat yang mengeksekusi perintah lain dan melakukan bagian pengeditan "inplace" karena itu dapat digunakan untuk menyediakan pengeditan "inplace" untuk POSIX, awk, grep, tr, apa pun dan tidak akan mengharuskan Anda untuk mengubah sintaks skrip Anda ke
print > out
dll. setiap kali Anda ingin mencetak nilai. Contoh sederhana, rapuh:yang akan Anda gunakan sebagai berikut:
Satu masalah yang jelas dengan
inedit
skrip itu adalah kesulitan mengidentifikasi file input / output secara terpisah dari perintah ketika Anda memiliki banyak file input. Script di atas mengasumsikan semua file input muncul sebagai daftar di akhir perintah dan perintah dijalankan terhadap mereka satu per satu, tetapi tentu saja itu berarti Anda tidak dapat menggunakannya untuk skrip yang memerlukan 2 file atau lebih pada suatu waktu, misalnya:atau skrip yang mengatur variabel antara file dalam daftar arg, mis:
Menjadikannya lebih tangguh dibiarkan sebagai latihan untuk pembaca tetapi melihat ke
xargs
sinopsis sebagai titik awal untuk bagaimana yang kuatinedit
harus bekerja :-).sumber
Solusi shell sederhana dan kemungkinan cukup cepat:
Hanya mencari solusi yang berbeda jika Anda secara meyakinkan menunjukkan bahwa ini terlalu lambat. Ingat: optimasi prematur adalah akar dari semua kejahatan.
sumber