Saya memiliki ~ 23000 baris SQL dump yang berisi beberapa data bernilai data. Saya perlu mengekstrak bagian tertentu dari file ini (yaitu data untuk database tunggal) dan menempatkannya di file baru. Saya tahu nomor awal dan akhir dari data yang saya inginkan.
Adakah yang tahu perintah Unix (atau serangkaian perintah) untuk mengekstrak semua baris dari file antara say line 16224 dan 16482 lalu mengarahkannya ke file baru?
unix
command-line
sed
text-processing
Adam J. Forster
sumber
sumber
Jawaban:
Dari manual sed :
dan
sumber
sed -n '16224,16482p;16483q' filename
. Kalau tidak, sed akan terus memindai sampai akhir (atau setidaknya versi saya lakukan).Di mana 16224.16482 adalah nomor baris awal dan nomor baris akhir, inklusif. Ini 1-diindeks.
-n
menekan gema input sebagai output, yang Anda jelas tidak inginkan; angka menunjukkan rentang garis untuk membuat perintah berikut beroperasi; perintahp
mencetak garis yang relevan.sumber
sed -n '16224,16482p;16482q' orig-data-file > new-file
.Cukup sederhana menggunakan kepala / ekor:
menggunakan sed:
menggunakan awk:
sumber
tail
.sed -n 16224,16482p' in.sql >out.sql
dan perintah awk harusawk 'NR>=16224&&NR<=16482' in.sql > out.sql
head -16482 in.sql | tail -$((16482-16224)) >out.sql
meninggalkan perhitungan ke bashtail -n +16224
untuk mengurangi perhitunganAnda bisa menggunakan 'vi' dan kemudian perintah berikut:
Kalau tidak:
EDIT: - Hanya untuk menambahkan penjelasan, Anda menggunakan head -n 16482 untuk menampilkan 16482 baris pertama kemudian gunakan tail -n 258 untuk mendapatkan 258 baris terakhir dari output pertama.
sumber
cat
perintah;head
dapat membaca file secara langsung. Ini lebih lambat daripada banyak alternatif karena menggunakan 2 (3 seperti yang ditunjukkan) perintah di mana 1 sudah cukup.cat
). Solusi lain memerlukan setidaknya beberapa menit. Juga variasi tercepat pada GNU tampaknyatail -n +XXX filename | head XXX
.Ada pendekatan lain dengan
awk
:Jika file tersebut berukuran besar, sebaiknya
exit
setelah membaca baris yang diinginkan terakhir. Dengan cara ini, tidak perlu membaca baris-baris berikut secara tidak perlu:sumber
print; exit
. Terima kasih!awk 'NR==16224, NR==16482; NR==16482 {exit}' file
sumber
sumber
harus melakukan trik. Kelemahan dari pendekatan ini adalah bahwa Anda perlu melakukan aritmatika untuk menentukan argumen untuk tail dan untuk memperhitungkan apakah Anda ingin 'antara' menyertakan garis akhir atau tidak.
sumber
cat
perintah;head
dapat membaca file secara langsung. Ini lebih lambat daripada banyak alternatif karena menggunakan 2 (3 seperti yang ditunjukkan) perintah di mana 1 sudah cukup.| tail -$((16482 - 16224))
.Berdiri di pundak boxxar, saya suka ini:
misalnya
The
$
berarti "baris terakhir", sehingga perintah pertama membuatsed
mencetak semua baris yang dimulai dengan garis16224
dan merek perintah keduased
berhenti setelah mencetak baris16428
. (Menambahkan1
untukq
-range dalam solusi boxxar tampaknya tidak diperlukan.)Saya suka varian ini karena saya tidak perlu menentukan nomor baris akhir dua kali. Dan saya mengukur bahwa menggunakan
$
tidak memiliki efek buruk pada kinerja.sumber
sed -n '16224,16482p' < dump.sql
sumber
Cepat dan kotor:
Mungkin bukan cara terbaik untuk melakukannya tetapi harus berhasil.
BTW: 259 = 16482-16224 + 1.
sumber
Saya menulis sebuah program Haskell bernama splitter yang melakukan hal ini: membaca melalui posting blog rilis saya .
Anda dapat menggunakan program ini sebagai berikut:
Dan hanya itu yang ada di sana. Anda akan membutuhkan Haskell untuk menginstalnya. Hanya:
Dan kamu sudah selesai. Saya harap Anda menemukan program ini bermanfaat.
sumber
splitter
hanya membaca dari input standar? Dalam arti tertentu, itu tidak masalah; yangcat
perintah berlebihan apakah itu dilakukan atau tidak. Baik menggunakansplitter 16224-16482 < somefile
atau (jika dibutuhkan argumen nama file)splitter 16224-16482 somefile
.Bahkan kita dapat melakukan ini untuk memeriksa di baris perintah:
Sebagai contoh:
sumber
cat
perintah di salah satu dari ini;sed
sangat mampu membaca file sendiri, atau Anda dapat mengarahkan input standar dari file.Menggunakan ruby:
sumber
Saya baru akan memposting trik kepala / ekor, tetapi sebenarnya saya mungkin baru saja menjalankan emacs. ;-)
buka file output baru, simpan ctl-y
Mari saya lihat apa yang terjadi.
sumber
Saya akan menggunakan:
FNR berisi nomor catatan (baris) dari baris yang sedang dibaca dari file.
sumber
Saya ingin melakukan hal yang sama dari skrip menggunakan variabel dan mencapainya dengan meletakkan tanda kutip di sekitar $ variabel untuk memisahkan nama variabel dari p:
Saya ingin membagi daftar menjadi folder yang terpisah dan menemukan pertanyaan awal dan menjawab langkah yang bermanfaat. (perintah split bukan opsi pada os lama saya harus port kode ke).
sumber
Saya menulis skrip bash kecil yang dapat Anda jalankan dari baris perintah Anda, asalkan Anda memperbarui PATH Anda untuk memasukkan direktori (atau Anda dapat menempatkannya di direktori yang sudah terkandung dalam PATH).
Penggunaan: $ pinch filename start-line end-line
sumber
wc
perintah, yang membuang-buang bandwidth disk, terutama pada file gigabyte. Dalam segala macam cara, ini didokumentasikan dengan baik, tetapi juga rekayasa berlebihan.Ini mungkin bekerja untuk Anda (sed GNU):
atau memanfaatkan bash:
sumber
Menggunakan ed:
-s
menekan keluaran diagnostik; perintah sebenarnya ada di sini-string. Secara khusus,16224,16482p
jalankan perintahp
(cetak) pada kisaran alamat jalur yang diinginkan.sumber
-N pada jawaban terima berfungsi. Berikut cara lain jika Anda ingin.
Ini melakukan hal berikut:
sumber
cat file | sed
lebih baik ditulis sebagaised file
Karena kita berbicara tentang mengekstraksi baris teks dari file teks, saya akan memberikan kasus khusus di mana Anda ingin mengekstraksi semua baris yang cocok dengan pola tertentu.
Akan mencetak baris [Data] dan sisanya. Jika Anda ingin teks dari line1 ke pola, Anda mengetik: sed -n '1, / Data / p' myfile. Selanjutnya, jika Anda tahu dua pola (lebih baik menjadi unik dalam teks Anda), baik garis awal dan akhir rentang dapat ditentukan dengan kecocokan.
sumber