Saya memiliki banyak file, beberapa di antaranya sangat panjang. Saya ingin memotongnya ke ukuran tertentu jika mereka lebih besar dengan menghapus ujung file. Tapi saya hanya ingin menghapus seluruh baris. Bagaimana saya bisa melakukan ini? Rasanya seperti hal yang akan ditangani oleh toolchain Linux tapi saya tidak tahu perintah yang tepat.
Misalnya, saya memiliki file 120.000 byte dengan 300-byte baris dan saya mencoba memotongnya menjadi 10.000 byte. 33 baris pertama harus tetap (9900 byte) dan sisanya harus dipotong. Saya tidak ingin memotong pada 10.000 byte persis, karena itu akan meninggalkan garis parsial.
Tentu saja file memiliki panjang yang berbeda dan garis-garisnya tidak semuanya sama panjang.
Idealnya file yang dihasilkan akan dibuat sedikit lebih pendek daripada sedikit lebih lama (jika breakpoint ada di garis panjang) tapi itu tidak terlalu penting, bisa jadi sedikit lebih lama jika itu lebih mudah. Saya ingin perubahan dilakukan langsung ke file (well, mungkin file baru disalin di tempat lain, yang asli dihapus, dan file baru dipindahkan, tapi itu sama dari POV pengguna). Sebuah solusi yang mengalihkan data ke banyak tempat dan kemudian kembali mengundang kemungkinan merusak file dan saya ingin menghindari itu ...
sumber
Jawaban:
The
sed
/wc
kompleksitas dapat dihindari dalam jawaban sebelumnya jikaawk
digunakan. Menggunakan contoh yang disediakan dari OP (menampilkan baris lengkap sebelum 10.000 byte):Juga menunjukkan baris lengkap yang berisi 10.000 byte jika byte itu tidak di akhir baris:
Jawaban di atas mengasumsikan:
\n
). Untuk file teks Dos / Windows (\r\n
), ubahlength() + 1
kelength() + 2
LC_CTYPE=C
untuk memaksakan interpretasi pada level byte.sumber
The
sed
pendekatan baik-baik saja, tapi loop atas semua lini tidak. Jika Anda tahu berapa banyak baris yang ingin Anda pertahankan (untuk memiliki contoh, saya menggunakan 99 di sini), Anda dapat melakukannya seperti ini:Penjelasan:
sed
adalah prosesor ekspresi reguler. Dengan opsi yang-i
diberikan, ia memproses file secara langsung ("inline") - alih-alih hanya membacanya dan menulis hasilnya ke output standar.100,$
hanya berarti "dari baris 100 hingga akhir file" - dan diikuti oleh perintahd
, yang mungkin Anda tebak dengan benar artinya "hapus". Jadi singkatnya, perintah itu berarti: "Hapus semua baris dari baris 100 ke akhir file dari myfile.txt". 100 adalah baris pertama yang akan dihapus, karena Anda ingin mempertahankan 99 baris.Sunting: Jika, di sisi lain, ada file log tempat Anda ingin menyimpan mis. 100 baris terakhir :
Apa yang terjadi disini:
[ $(wc -l myfile.txt) -gt 100 ]
: lakukan langkah-langkah berikut hanya jika file memiliki lebih dari 100 baris$((100 - $(wc -l myfile.txt|awk '{print $1}')))
: menghitung jumlah baris yang akan dihapus (yaitu semua baris file kecuali (terakhir) yang dipertahankan 100)1, $((..)) d
: hapus semua baris dari baris pertama hingga baris yang dihitungEDIT: karena pertanyaannya baru saja diedit untuk memberikan rincian lebih lanjut, saya akan memasukkan informasi tambahan ini dengan jawaban saya juga. Fakta yang ditambahkan adalah:
Dari data ini dimungkinkan untuk menghitung jumlah baris untuk tetap sebagai "/", yang dengan contoh berarti 33 baris. Istilah shell untuk perhitungan:
$((size_to_remain / linesize))
(setidaknya di Linux menggunakan Bash, hasilnya adalah integer). Perintah yang disesuaikan sekarang akan berbunyi:Karena ukuran diketahui sebelumnya, tidak ada lagi kebutuhan untuk perhitungan yang melekat pada
sed
perintah. Tetapi untuk fleksibilitas, di dalam beberapa skrip shell kita dapat menggunakan variabel.Untuk pemrosesan bersyarat berdasarkan ukuran file, seseorang dapat menggunakan "test" berikut ini:
yang berarti: "jika ukurannya
$file
melebihi 100kB, lakukan ..." (ls -lk
daftar ukuran file dalam kB pada posisi 5, makaawk
digunakan untuk mengekstrak persis ini).sumber
head -n
.Gagal menemukan perintah untuk melakukan ini, saya menulis skrip cepat (tidak diuji):
sumber
Anda dapat menggunakan perintah linux sed untuk menghapus baris dari file. Perintah berikut menghapus baris terakhir dari filename.txt:
Dengan awk atau temukan, Anda dapat mencari pola yang cocok dengan perintah sed Anda. Pertama Anda mencari dengan awk atau mencari file yang ingin Anda persingkat dan kemudian Anda dapat menghapus garis dengan sed.
sumber
Saya melakukan sesuatu yang mirip dengan ekor. Untuk hanya menyimpan 10.000 baris terakhir dalam hal ini:
sumber