Ekstrak bagian tengah baris file teks?

17

Saya menulis skrip PHP untuk mem-parsing file teks besar untuk melakukan sisipan database darinya. Namun pada host saya, file tersebut terlalu besar, dan saya menekan batas memori untuk PHP.

File ini memiliki sekitar 16.000 baris; Saya ingin membaginya menjadi empat file terpisah (pada awalnya) untuk melihat apakah saya dapat memuatnya.

Bagian pertama yang bisa saya dapatkan head -4000 file.txt. Bagian tengah sedikit lebih rumit - saya berpikir tentang mem-piping tailoutput ke head( tail -4001 file.txt | head -4000 > section2.txt), tetapi apakah ada cara lain yang lebih baik?

Sebenarnya logika saya kacau - untuk bagian dua, saya perlu sesuatu seperti itu tail -12001 file.txt | head - 4000, dan kemudian turunkan tailargumen untuk bagian berikutnya. Saya sudah terlibat! : P

pengguna394
sumber

Jawaban:

27

Jika Anda ingin tidak kacau tapi tetap melakukannya menggunakan taildan head, ada cara yang berguna untuk tailmenggunakan garis-hitung dari awal, bukan akhir:

tail -n +4001 yourfile | head -4000

... Tetapi alat otomatis yang lebih baik dan dibuat khusus untuk memisahkan file disebut ... split! Ini juga merupakan bagian dari GNU coreutils, jadi setiap sistem Linux normal harus memilikinya. Inilah cara Anda dapat menggunakannya:

split -l 4000 yourInputFile thePrefixForOutputFiles

(Lihat man splitapakah ragu-ragu.)

rozcietrzewiacz
sumber
19

Menggabungkan kepala dan ekor seperti yang Anda lakukan akan berhasil, tetapi untuk ini saya akan gunakan sed

sed -n '1,4000p' input_file # print lines 1-4000 of input_file

Ini memungkinkan Anda memecahkan masalah Anda dengan fungsi shell cepat

chunk_it(){
    step=4
    start=1
    end=$step
    for n in {1..4} ; do
        sed -n "${start},${end}p" "$1" > "$1".$start-$end
        let start+=$step
        let end+=$step
    done
}

chunk_it your_file

Sekarang Anda memiliki file_file.1-4000 dan yuor_file.4001-8000 Anda dan seterusnya.

Catatan: membutuhkan bash

Sorpigal
sumber
3
Saya suka cara sed.
fanchyna
Ini tidak bekerja untuk saya karena sed tidak keluar. Ini mencetak garis yang ingin saya stdout, tapi saya harus ctrl-c, dan sebagai hasilnya, saya tidak bisa mengarahkan ulang ke file. Adakah saran untuk membuatnya dapat digunakan?
Brent212
Menemukannya! "sed -n '<start_line>, <end_line> w <output_file>' <input_file>" bekerja untuk saya.
Brent212
@ Brent212 Pilihan lain yang perlu diperhatikan adalah Anda juga bisa mengurangi atau mengalihkan output ke file.
Kyle s