Eu tenho um grande número de arquivos de log, em uma caixa Linux, preciso limpar dados confidenciais antes de enviá-los a terceiros. Eu usei o script abaixo em ocasiões anteriores para realizar esta tarefa e funcionou perfeitamente (o script foi construído com alguma ajuda daqui :-)):
#!/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 de nossos departamentos me enviou um CLIENT_FILE.txt com425.000+variáveis! Acho que posso ter atingido algum limite interno! Se alguém tiver uma idéia de como lidar com tantas variáveis, eu realmente apreciaria.
Tentei dividir o arquivo do cliente em 4 com cerca de 100.000 variáveis em cada, mas ainda não funciona. Detesto continuar dividindo, pois tenho 20 diretórios com até 190 arquivos em cada diretório para percorrer. Quanto mais arquivos de cliente eu fizer, mais passagens terei que fazer.
Responder1
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 seus arquivos de log tiverem algo além de simples linhas delimitadas por espaço, o script awk poderá atrapalhar a formatação.
Responder2
Você deve tentar escrever o sed
padrão em um arquivo e passá-lo sed
com a opção --file=
. Os parâmetros da linha de comando não se destinam a transmitir grandes blocos de dados.