Verwenden von sed zum Ersetzen einer *großen* Anzahl von Variablen in einer Datei

Verwenden von sed zum Ersetzen einer *großen* Anzahl von Variablen in einer Datei

Ich habe eine große Anzahl von Protokolldateien auf einer Linux-Box, aus denen ich vertrauliche Daten löschen muss, bevor ich sie an Dritte sende. Ich habe das folgende Skript bei früheren Gelegenheiten verwendet, um diese Aufgabe auszuführen, und es hat hervorragend funktioniert (das Skript wurde mit etwas Hilfe von hier erstellt :-)):

#!/bin/bash

help_text () {
cat <<EOF
Usage: $0 [log_directory] [client_name(s)]
EOF
exit 0
}

CMDLINE=""$0" "$@""
if [ -z "$1" ]; then
        help_text
else

        pattern=""
        delim=""
        n=1

        counter=`find "$1" -name *.gz |sort |wc -l`

        BAKIFS=$IFS
        IFS=$(echo -en "\n\b")
        exec 3<&0
        exec 0<"$2"
        while read -r line
        do
                pattern=$pattern$delim$line
                delim="|"
        done
        exec 0<&3
        IFS=$BAKIFS

        while [ $n -lt $counter ]
        do
                for i in `find "$1" -name *.gz |sort`
                do
                        gunzip "$i"
                        i_unzip=$(echo "$i" |sed 's/\.[^\.]*$//')
                        sed -ri "s/$pattern/CLIENT/g" "$i_unzip"
                        gzip "$i_unzip"
                done
                n=n+1
        done
fi
exit 0

Nun hat mir jedoch eine unserer Abteilungen eine CLIENT_FILE.txt geschickt mit425.000+Variablen! Ich glaube, ich bin an eine interne Grenze gestoßen! Wenn jemand eine Idee hat, wie man mit so vielen Variablen umgehen kann, wäre ich sehr dankbar.

Ich habe versucht, die Client-Datei in 4 Teile mit jeweils etwa 100.000 Variablen aufzuteilen, aber das funktioniert immer noch nicht. Ich bin allerdings nicht bereit, weiter aufzuteilen, da ich 20 Verzeichnisse mit jeweils bis zu 190 Dateien durchgehen muss. Je mehr Client-Dateien ich erstelle, desto mehr Durchgänge muss ich machen.

Antwort1

Ich würde so etwas versuchen:

#!/bin/bash

files=()
while read file; do
    gunzip "$file"  &&  files+=( "${file%.gz}" )
done < <(find "$1" -name '*.gz')

awk '
    FILENAME == ARGV[1] {
        client_name[$0]++
        next
    }
    FNR == 1 {
        output = FILENAME ".new"
    }
    {
        for (i=1; i<=NF; i++) {
            if ($i in client_name)
                $i = "CLIENT"
        }
        print > output
    }
' "$2" "${files[@]}"

for file in "${files[@]}"; do
    mv "$file" "$file.old"  &&
    mv "$file.new" "$file"  &&
    gzip "$file"
done

Wenn Ihre Protokolldateien mehr als einfache, durch Leerzeichen getrennte Zeilen enthalten, kann das Awk-Skript die Formatierung stören.

Antwort2

Sie sollten versuchen, das Muster in eine Datei zu schreiben sedund es sedmit der Option zu übergeben --file=. Befehlszeilenparameter sind nicht dafür gedacht, große Datenmengen zu übergeben.

verwandte Informationen