Usar sed para reemplazar una *gran* cantidad de variables en un archivo

Usar sed para reemplazar una *gran* cantidad de variables en un archivo

Tengo una gran cantidad de archivos de registro, en una máquina Linux, necesito limpiar datos confidenciales antes de enviarlos a un tercero. He utilizado el siguiente script en ocasiones anteriores para realizar esta tarea y ha funcionado de manera brillante (el script se creó con ayuda de aquí :-)):

#!/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

Sin embargo, ahora uno de nuestros departamentos me ha enviado un CLIENT_FILE.txt con425000+variables! ¡Creo que he alcanzado algún límite interno! Si alguien tiene una idea sobre cómo lidiar con tantas variables, realmente se lo agradecería.

Intenté dividir el archivo del cliente en 4 con alrededor de 100000 variables en cada uno, pero esto todavía no funciona. Sin embargo, detesto seguir dividiéndome, ya que tengo 20 directorios con hasta 190 archivos en cada directorio para ejecutar. Cuantos más archivos de cliente hago, más pases tengo que hacer.

Respuesta1

Intentaría algo como esto:

#!/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

Si sus archivos de registro tienen algo más que simples líneas delimitadas por espacios, el script awk puede alterar el formato.

Respuesta2

Deberías intentar escribir el sedpatrón en un archivo y pasarlo sedcon la opción --file=. Los parámetros de la línea de comando no están destinados a transmitir grandes cantidades de datos.

información relacionada