8 Gb günlük dosyam var (Rails üretim günlüğü). Bazı tarihler (satırlar) arasında kesmem gerekiyor. Bunu yapmak için hangi komutu kullanabilirim?
sed
zaman kolayca yapacağız.
8 Gb günlük dosyam var (Rails üretim günlüğü). Bazı tarihler (satırlar) arasında kesmem gerekiyor. Bunu yapmak için hangi komutu kullanabilirim?
sed
zaman kolayca yapacağız.
Yanıtlar:
Gibi bir şey
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
dosyaya nelerin konulduğunu görmenizi sağlar cut-log
.
DÜZENLE:
Fred.bear'ın titiz standartlarını karşılamak için işte bir sed çözümü (tartışmasız awk çözümü çok daha güzel olsa da):
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
eşleşebileceğini bilmek awk
ve aslında biraz daha hızlıydı.
FOO ve BAR dahil her şeyi yazdırmak için şunu deneyin:
$ sed -n '/FOO/,/BAR/p' file.txt
Bu istediğinizi yapacak ...
Parametre tarihlerini Dahil Etme ve Hariç Tutma gösterilir.
# 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"
Alan 2'de (sıralı) bir tarihi test eder ... İşte test verileri için bir örnek
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
Ve işte test veri üreteci .
awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
if
ifadenin süresi (hatta satır başına 1 değil) yani. mantık akışı etkili bir şekilde aynıdır ve çalışma süresindeki fark nanosaniye cinsinden sayılır. "Başka" kullanmamamın tek nedeni, bu benim ilk senaryom (bir gün 4 yıl dışında) önce bazı örneklerle oynadığımda) ... ve bulduğum ilk uygulanabilir dal mekanizması ... (ve belirtildiği gibi. bu kadar hızlı) .. Genellikle Tryawk
sed
q
Günlük dosyanızda bu biçimde tarihler varsa, YYYY-MM-DD
örneğin 2011-02-10 için tüm girişleri bulmak için şunları yapabilirsiniz:
grep 2011-02-10 log_file
Şimdi, 2011-02-10 ve 2011-02-11 için girişleri bulmak istiyorsanız, tekrar kullanın, grep
ancak birden çok desenle kullanın :
grep -E '2011-02-10|2011-02-11' log_file
grep
yapıldığı gibi" çalışır :) ... Ancak, tarih aralığı dosyanın başında olsa bile dosyanın tamamını arar . Ortalama olarak, bu, aramanın süresini "aralıktaki son öğeden sonra çıkış" ile karşılaştırıldığında iki katına çıkarır ... Bunu yalnızca, 8 GB dosya boyutunda, grep süresi sonuçları buradaki sed örneğiyle hemen hemen aynıdır (1dk 58sn). Benim zaman testler sonuçları link: paste.ubuntu.com/573477
Bu boyuttaki dosyalarla çalışmak her zaman zordur.
Bir yol bu dosyayı birkaç küçük dosyaya bölmek olabilir, bunu yapmak için split komutunu kullanabilirsiniz.
split -d -l 50000 ToBigFile.data file_
Bölünmüş olsanız bile, hala bir bash for loop kullanarak bir dosya gibi çalışabilirsiniz
for f in `ls file_*`; do cat $f; done;
Ancak kedi yerine, istenmeyen verilerden kurtulmak için ters grep kullanabilirsiniz, bunun için önemsizdir. (veya ihtiyacınız olan ayrıntılandırma türünü).
Bu noktada sadece çok daha küçük dosyalarla çalışacaksınız ve yukarıda belirtilen diğer komutlar çok daha küçük dosyalarda daha sorunsuz çalışacaktır.
Ve işiniz bittiğinde, yeni küçük dosyayı tekrar oluşturmak için bir saniye döngü kullanabilirsiniz.
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
Güncelleme Verileri birden fazla dosyaya bölmeye başladığımızdan beri, sabit sürücüde çok fazla iş olacak ve bu da zaman alıyor. (Bu soruda görünüşe göre 5dk).
Öte yandan, sonraki adımlar muhtemelen daha hızlı olacaktır.
Yani bu yöntem muhtemelen basit grep, awk, sed işlemi için anlamsızdır, ancak arama desenleri daha karmaşık hale gelirse daha hızlı olabilir.
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file