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 sed
patrón en un archivo y pasarlo sed
con la opción --file=
. Los parámetros de la línea de comando no están destinados a transmitir grandes cantidades de datos.