Usando sed para substituir um número * grande * de variáveis em um arquivo

0

Eu tenho um grande número de arquivos de log, em uma caixa Linux, eu preciso limpar os dados confidenciais antes de enviar para terceiros. Eu usei o script abaixo em ocasiões anteriores para executar essa tarefa e ela funcionou de forma brilhante (o script foi criado com alguma ajuda aqui :-)):

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

No entanto, agora um dos nossos departamentos enviou-me um CLIENT_FILE.txt com 425000 + variáveis! Eu acho que posso ter atingido algum limite interno! Se alguém tiver uma ideia de como lidar com essas muitas variáveis, eu realmente aprecio isso.

Eu tentei dividir o arquivo do cliente em 4 com cerca de 100.000 variáveis em cada, isso ainda não funciona. Eu detesto continuar a dividir embora, como eu tenho 20 diretórios com até 190 arquivos em cada diretório para percorrer. Quanto mais arquivos do cliente eu faço, mais passes eu tenho que fazer.

    
por Steve 28.07.2011 / 11:51

2 respostas

1

Eu tentaria algo assim:

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

Se os seus arquivos de log tiverem algo além de simples linhas delimitadas por espaço, o script awk pode interromper a formatação.

    
por 28.07.2011 / 14:23
0

Você deve tentar gravar o padrão sed em um arquivo e passá-lo para sed com a opção --file= . Parâmetros de linha de comando não devem passar grandes blocos de dados.

    
por 28.07.2011 / 13:44