> 2GB metin dosyasındaki 6000+ karakter dizisini değiştirmek


0

> 2GB metin dosyasında 6000'den fazla dizeyi aramak ve değiştirmek istiyorum.

sed -i "s/search/replace/g" 2gbfile.log

Sonsuza dek alıyor. Özellikle 6000'den fazla kez yapmanız gerekiyorsa.

Bu yüzden 2 GB dosyasını parçalara ayıran bir komut dosyası buldum, böylece çabayı paralelleştirebiliyorum. Aynı anda 48 işlem yürütüyorum (64 çekirdek kullanılabilir), ancak yine de oldukça uzun sürüyor.

#!/usr/bin/env bash

echo "sorting..."
sort bigbigbigfile | awk -F, '{print $2,$1,$3}' > bigbigbigfile.work

CPUS=$(( $(lscpu |grep "On-line CPU(s) list"|grep -Eo '0-[0-9]+'|cut -f2 -d-) + 1))
CPUSUSABLE=$(echo "$CPUS*0.75" | bc | cut -f1 -d.)
NUMLINES=$(cat all-temperatures.sort | wc -l)
SPLIT=$(echo "$NUMLINES / $CPUSUSABLE" | bc | cut -f1 -d.)
echo "cutting..."
split -l $SPLIT bigbigbigfile.work chunkstoworkwith

mapfile -t REPLACEME < replace.list

echo "seding..."
for chunk in $(ls chunkstoworkwith*); do
        (
        for i in "${!REPLACEME[@]}"; do
                counter=$(( counter + 1 ))
                sed -i "s/ ${REPLACEME[$i]} / $counter /g" $chunk
        done
        ) &
done

Bu çalışıyor. Ancak, bellekte arama ve değiştirme işleminde daha hızlı olabileceğini düşünüyorum, yerine yerinde değişiklik yapmaktan ve 48 dosyada 6000'den fazla değişiklik yapmak yerine. Bu neredeyse 300k adede kadar çağrıyı toplar ve bu da birçok dosya açma / kapama / yazma / neyse sonuçlanır.

Bunun nasıl hızlandırılacağı ve bellekteki değişimlerin nasıl yapılacağı ve her şey değiştikten sonra verilerin silinmesi konusunda bir fikrin var mı?


HI HansPeter. SuperUser'a hoş geldiniz. Bash komut dosyasını içerdiği için, bu soru SuperUser yerine StackOverflow'ta daha iyi cevaplanmış gibi görünmektedir. orada bu soruyu sordun mu
Stese

Yanıtlar:


2

Komut dosyasınız her değişim için tüm öbekleri ayrıştırıyor!

Yani, her bir öbek için, komut dosyası açılır, tüm satırlardan geçer, muhtemelen 1 değişiklik yapar, dosyayı kapatır ve orijinal dosyayı taşır ( -iseçenek nedeniyle ).

Deseni sayma numarasıyla değiştirmek isterseniz, her değiştirmede aynı anda tüm değiştirmeleri gerçekleştirmenin bir yolu:

sed -f <(awk '{print "s/ "$1" / "++c" /"}' replace.list) -i "$chunk"

Bu -fseçenek girdi olarak sed betiğin alınmasına izin verir ve $chunkdosyanın tüm satırları için bir kerede yürütülür .

Bu genel zamanlamayı azaltacaktır ...


Kabul. İlk gelişme, tüm değişikliklerin bir dosya erişiminde yapılmasıdır.
ksenoid

0

Ben senin kadar yavaş gidiyor sed neden tamamen emin değilim, muhtemelen hata ayıklamak ya da daha yakın gerçekten öğrenmek için izlemek, ancak 6.000 kez yazmaya çalışıyor ise ve bu kadar yavaşlatan var olur, sen atlamak -ive sadece sed (bütün) dosyayı bir kere yazdıktan sonra:

sed "s/search/replace/g" 2gbfile.log > 2bgfile-AfterSed.log

Bu ayrıca 6000 ayarlı çağrı yapılmasını da gerektirecektir (değiştirilmesi gereken her model için) ve paralelleştirilemez.
HansPeter

Sed sadece bir kez koşuyor, bir kez okuyor ve bir kez yazıyor ve sanırım çok yavaş olan yerinde yazma olabilir. Bu yöntem ne kadar sürer?
Xen2050

$ time sed "s/search/replace/g" 2gbfile.log > 2bgfile-AfterSed.log #real 0m18.451s
HansPeter,

(18 x 6000) / 3600 = 30 saat.
HansPeter,

Bu sadece 2GB dosyanın 1 / 6000'inde. Neyse, tıkanıklığın nerede olduğunu bilmeden temelde sadece tahmin ediyoruz, genellikle okur ve yazar, temel bir bulma / değiştirme gibi tüm hesaplamalardan çok daha yavaştır
Xen2050
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.