Saya memiliki file log 8 Gb (log produksi Rails). Saya perlu memotongnya di antara beberapa tanggal (garis). Perintah mana yang bisa saya gunakan untuk melakukan ini?
sed
akan melakukannya dengan mudah.
Saya memiliki file log 8 Gb (log produksi Rails). Saya perlu memotongnya di antara beberapa tanggal (garis). Perintah mana yang bisa saya gunakan untuk melakukan ini?
sed
akan melakukannya dengan mudah.
Jawaban:
Sesuatu seperti
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
memungkinkan Anda melihat di layar apa yang dimasukkan ke dalam file cut-log
.
EDIT:
Untuk memenuhi standar menuntut fred.bear, inilah solusi sed (meskipun solusi awk bisa dibilang jauh lebih cantik):
b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"
sed
bisa cocok awk
untuk kecepatan, dan itu sebenarnya sedikit lebih cepat.
Untuk mencetak semuanya antara FOO dan BAR termasuk, coba:
$ sed -n '/FOO/,/BAR/p' file.txt
Ini akan melakukan apa yang Anda inginkan ...
Termasuk dan tidak termasuk tanggal parameter ditampilkan.
# set Test args
set 2011-02-24 2011-02-26 "junk"
from="$1"
till="$2"
file="$3"
# EITHER ==== +++++++++
# Ouptut lines between two parameter dates INCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 >= from) && ($2 <= till) { print $0 ; next }
($2 > till) { exit }' "$file"
# OR ======== ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 > from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
Ini menguji untuk tanggal (diurutkan) di bidang 2 ... Berikut ini adalah contoh untuk data pengujian
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
Dan di sini adalah generator uji-data .
awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
if
pernyataan tambahan secara total (bahkan 1 per baris) yaitu. alur logikanya sama, dan perbedaan dalam run time akan dihitung dalam nanodetik .... Satu-satunya alasan saya tidak menggunakan "lain" adalah karena ini secara efektif merupakan awk
skrip pertama saya (selain dari satu hari 4 tahun) lalu ketika saya bermain dengan beberapa contoh) ... dan itu adalah mekanisme cabang yang bisa diterapkan pertama yang saya temukan ... (dan seperti yang disebutkan. Ini sama cepatnya) .. Saya secara umum menggunakan sed
Tryq
Jika dalam file log Anda, Anda memiliki tanggal dalam format ini YYYY-MM-DD
, maka, untuk menemukan semua entri misalnya, 2011-02-10, Anda dapat melakukan:
grep 2011-02-10 log_file
Sekarang, katakanlah, jika Anda ingin menemukan entri untuk 2011-02-10 dan 2011-02-11, maka, sekali lagi gunakan grep
tetapi dengan beberapa pola:
grep -E '2011-02-10|2011-02-11' log_file
grep
akan mencari seluruh file, bahkan jika rentang tanggal di awal file. Rata-rata ini menggandakan waktu pencarian, bila dibandingkan dengan "keluar-setelah-item-terakhir-dalam-jangkauan" ... Saya hanya repot menyebutkan ini karena ukuran file 8 GB yang disebutkan dalam pertanyaan, Anda hasil grep waktu hampir identik dengan contoh sed di sini (1 menit 58detik). Inilah tautan ke hasil tes waktu saya: paste.ubuntu.com/573477
Bekerja dengan ukuran file ini selalu sulit.
Cara ke depan bisa dengan membagi file ini menjadi beberapa yang kecil, untuk melakukan ini Anda dapat menggunakan perintah split.
split -d -l 50000 ToBigFile.data file_
Meskipun Anda sudah berpisah Anda masih dapat bekerja dengan file seperti jika akan menggunakan bash untuk loop
for f in `ls file_*`; do cat $f; done;
Tapi alih-alih kucing Anda dapat menggunakan grep terbalik untuk menyingkirkan data yang tidak diinginkan, itu tidak relevan untuk ini. (atau jenis penyempurnaan yang Anda butuhkan).
Pada titik ini Anda hanya akan bekerja dengan banyak file yang lebih kecil, dan perintah yang disebutkan di atas akan bekerja lebih baik pada banyak file yang lebih kecil.
Dan setelah selesai, Anda dapat menggunakan perulangan kedua untuk membuat kembali file yang lebih kecil.
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
Pembaruan Karena kami mulai membagi data menjadi beberapa file, akan ada banyak pekerjaan dengan harddisk dan itu membutuhkan waktu. (Dalam pertanyaan ini rupanya 5 menit).
Di sisi lain langkah selanjutnya mungkin akan lebih cepat.
Jadi metode ini mungkin tidak ada gunanya untuk operasi sederhana grep, awk, sed, tetapi jika pola pencarian menjadi lebih rumit itu bisa menjadi lebih cepat.
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file