Saya memiliki file teks bernama entry.txt
yang berisi yang berikut ini:
[ entry1 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3633 3634 3636 3690 3691 3693 3766
3767 3769 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5628 5629 5631
[ entry2 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4526
4527 4529 4583 4584 4586 4773 4774 4776 5153 5154
5156 5628 5629 5631
[ entry3 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4241
4242 4244 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5495 5496 5498 5628 5629 5631
Saya ingin membaginya menjadi tiga file teks: entry1.txt
, entry2.txt
, entry3.txt
. Isinya sebagai berikut.
entry1.txt :
[ entry1 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3633 3634 3636 3690 3691 3693 3766
3767 3769 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5628 5629 5631
entry2.txt :
[ entry2 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4526
4527 4529 4583 4584 4586 4773 4774 4776 5153 5154
5156 5628 5629 5631
entry3.txt :
[ entry3 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4241
4242 4244 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5495 5496 5498 5628 5629 5631
Dengan kata lain, [
karakter menunjukkan file baru harus dimulai. Entri ( [ entry*]
, di mana *
bilangan bulat) selalu dalam urutan numerik dan bilangan bulat berturut-turut mulai dari 1 hingga N (dalam file input aktual saya, N = 200001).
Apakah ada cara saya bisa menyelesaikan pemisahan file teks otomatis di bash? Input saya yang sebenarnya entry.txt
sebenarnya berisi 200.001 entri.
sumber
match
masuk:/^\[/ { name=$2 }
sudah cukup.[ blahblah blah blah ]
dalam jawaban saya.FS
, misalnya-F '\\[ | \\]'
.#S x
, di mana x adalah angka 1, 2, atau 3 digit. Hanya menyimpannya ke x.dat sudah cukup. Saya mencoba:gawk '/^#S/{match($0, / [0-9]* /, k)} {print >k[1]".dat" }' myFile.txt
dan beberapa variasi dari itu.gawk '/^#S/{match($0, /^#S (\s+?)([0-9]+)(\s+?)/, k)} {print >k[2]".txt" }' test.txt
berhasil. Namun, tidak terlalu memahami nomor array2
.Dengan csplit dari GNU coreutils (Linux yang tidak tertanam, Cygwin):
Anda akan berakhir dengan file kosong tambahan
entry0.txt
(berisi bagian sebelum tajuk pertama).Csplit standar tidak memiliki
{*}
repeater tidak terbatas dan-b
opsi untuk menentukan format suffix, jadi pada sistem lain Anda harus menghitung jumlah bagian terlebih dahulu dan mengganti nama file output setelahnya.sumber
Dalam perl itu dapat dilakukan jauh lebih sederhana:
sumber
Berikut ini adalah satu kalimat pendek awk:
Bagaimana cara kerjanya?
/^\[/
cocok dengan garis yang dimulai dengan braket persegi kiri, dan{ofn=$2 ".txt"}
menetapkan variabel ke kata spasi putih-dibatasi kedua sebagai nama file output kami. Kemudian,ofn
adalah kondisi yang bernilai true jika variabel disetel (sehingga menyebabkan baris sebelum header pertama Anda diabaikan){print > ofn}
mengalihkan garis saat ini ke file yang ditentukan.Perhatikan bahwa semua ruang dalam skrip awk ini dapat dihapus, jika kekompakan membuat Anda bahagia.
Perhatikan juga bahwa skrip di atas benar-benar membutuhkan tajuk bagian untuk memiliki ruang di sekitarnya dan bukan di dalamnya. Jika Anda ingin dapat menangani header bagian seperti
[foo]
dan[ this that ]
, Anda memerlukan kode yang sedikit lebih banyak:Ini menggunakan
sub()
fungsi awk untuk menghapus tanda kurung dan spasi spasi. Perhatikan bahwa per perilaku standar awk, ini akan menciutkan spasi (pemisah bidang) menjadi satu ruang tunggal (yaitu[ this that ]
disimpan ke"this that.txt"
). Jika mempertahankan spasi putih asli dalam nama file output Anda penting, Anda dapat bereksperimen dengan menetapkan FS.sumber
Ini dapat dilakukan dari baris perintah dengan python sebagai:
sumber
Ini adalah cara yang agak kasar, tetapi mudah dipahami untuk melakukannya: gunakan
grep -l '[ entry ]' FILENAME
untuk mendapatkan nomor baris untuk dipecah pada [entri]. Gunakan kombinasi dari kepala dan ekor untuk mendapatkan potongan yang tepat.Seperti yang saya katakan; itu tidak cantik, tetapi mudah untuk dipahami.
sumber
Bagaimana dengan menggunakan awk dengan
[
sebagai pemisah catatan dan ruang sebagai pemisah bidang. Ini memberi kita dengan mudah data yang akan dimasukkan ke dalam file sebagai$0
tempat ia harus meletakkan kembali lead yang dihapus[
dan nama file sebagai$1
. Kami kemudian hanya perlu menangani kasus khusus dari catatan 1 yang kosong. Ini memberi kita:sumber
Jawaban terdon bekerja untuk saya, tetapi saya perlu menggunakan gawk, bukan awk. The pengguna melongo (mencari 'match (') menjelaskan bahwa argumen array dalam pertandingan () adalah ekstensi melongo. Mungkin itu tergantung pada Linux Anda menginstal dan awk / nawk / melongo versi Anda, tetapi pada mesin Ubuntu saya hanya sangat baik melongo ran Terdon ini menjawab:
sumber
Inilah solusi perl. Script ini mendeteksi
[ entryN ]
garis dan mengubah file output sesuai, tetapi tidak memvalidasi, mem-parsing atau memproses data di setiap bagian, ini hanya mencetak garis input ke file output.sumber
Hai saya menulis skrip sederhana ini menggunakan ruby untuk menyelesaikan masalah Anda
Anda dapat menggunakannya dengan cara ini:
saya telah mengujinya, dan berfungsi dengan baik ..
sumber
Saya lebih suka
csplit
opsi tetapi sebagai alternatif inilah solusi awk GNU:parse.awk
Jalankan seperti ini:
sumber
RT
variabel tampaknya spesifik-gawk. Solusi ini tidak berfungsi untuk saya menggunakan awk FreeBSD.