Büyük dosyalar ve ile ilgili garip bir sorunum var bash. Bağlam budur:
- Büyük bir dosyam var: 75G ve 400.000.000+ satır (bir günlük dosyası, kötüyüm, büyümesine izin verdim).
- Her satırın ilk 10 karakteri YYYY-AA-GG biçimindeki zaman damgalarıdır.
- O dosyayı bölmek istiyorum: günde bir dosya.
Ben işe yaramadı aşağıdaki komut dosyası ile denedim. Benim sorum bu betik çalışmıyor, alternatif çözümler değil .
while read line; do
new_file=${line:0:10}_file.log
echo "$line" >> $new_file
done < file.log
Hata ayıklama sonra, new_filedeğişkende sorun buldum . Bu komut dosyası:
while read line; do
new_file=${line:0:10}_file.log
echo $new_file
done < file.log | uniq -c
aşağıdaki sonucu verir ( xVerileri gizli tutmak için es koymak , diğer karakter gerçek olanlar). dhVe daha kısa dizelere dikkat edin :
...
27402 2011-xx-x4
27262 2011-xx-x5
22514 2011-xx-x6
17908 2011-xx-x7
...
3227382 2011-xx-x9
4474604 2011-xx-x0
1557680 2011-xx-x1
1 2011-xx-x2
3 2011-xx-x1
...
12 2011-xx-x1
1 2011-xx-dh
1 2011-xx-x1
1 208--
1 2011-xx-x1
1 2011-xx-dh
1 2011-xx-x1
...
Benim dosya biçiminde bir sorun değil . Komut dosyası cut -c 1-10 file.log | uniq -cyalnızca geçerli zaman damgaları verir. İlginçtir, yukarıdaki çıktının bir kısmı şu şekilde olur cut ... | uniq -c:
3227382 2011-xx-x9
4474604 2011-xx-x0
5722027 2011-xx-x1
Uniq sayımından sonra 4474604ilk betiğimin başarısız olduğunu görebiliriz.
Bash'ta bilmediğim bir sınıra girdim mi, bash'da bir hata buldum mu (olası dikişler) mi, yoksa yanlış bir şey mi yaptım?
Güncelleme :
Sorun, dosyanın 2G'sini okuduktan sonra ortaya çıkar. Dikişler readve yönlendirme 2G'den daha büyük dosyaları sevmez. Ama yine de daha kesin bir açıklama arıyor.
Güncelleme2 :
Kesinlikle bir hata gibi görünüyor. Şununla çoğaltılabilir:
yes "0123456789abcdefghijklmnopqrs" | head -n 100000000 > file
while read line; do file=${line:0:10}; echo $file; done < file | uniq -c
ancak bu bir geçici çözüm olarak iyi çalışır (yararlı bir kullanım bulduğum dikişler cat):
cat file | while read line; do file=${line:0:10}; echo $file; done | uniq -c
GNU ve Debian'a bir hata bildirildi. Etkilenen sürümler bashDebian Squeeze 6.0.2 ve 6.0.4 üzerinde 4.1.5'tir.
echo ${BASH_VERSINFO[@]}
4 1 5 1 release x86_64-pc-linux-gnu
Update3:
Hata raporuma hızlı tepki veren Andreas Schwab sayesinde, bu yanlış davranışın çözümü olan yama bu. Etkilenen dosya, lib/sh/zread.cGilles'in daha önce işaret ettiği gibi:
diff --git a/lib/sh/zread.c b/lib/sh/zread.c index 0fd1199..3731a41 100644
--- a/lib/sh/zread.c
+++ b/lib/sh/zread.c @@ -161,7 +161,7 @@ zsyncfd (fd)
int fd; { off_t off;
- int r;
+ off_t r;
off = lused - lind; r = 0;
rDeğişken dönüş değeri tutmak için kullanılır lseek. Gibi lseekdöner dosyanın başından mahsup o 2GB bittiğinde, intdeğer testi neden olan negatif if (r >= 0)bunun başarılı olması gereken yerde başarısız.
readifadenin bir sınırı yönünde işaret eder .