У меня есть большое количество файлов журнала на Linux-ящике, мне нужно очистить конфиденциальные данные перед отправкой третьей стороне. Я использовал следующий скрипт в предыдущих случаях для выполнения этой задачи, и он работал блестяще (скрипт был создан с некоторой помощью отсюда :-) ):
#!/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
Однако теперь один из наших отделов прислал мне файл CLIENT_FILE.txt с425000+переменные! Кажется, я наткнулся на какой-то внутренний предел! Если у кого-то есть идея, как справиться с таким количеством переменных, я буду очень признателен.
Я пробовал разделить клиентский файл на 4 с примерно 100000 переменных в каждом, это все еще не работает. Мне не нравится продолжать разделять, так как у меня 20 каталогов с 190 файлами в каждом каталоге, которые нужно пройти. Чем больше клиентских файлов я делаю, тем больше проходов мне нужно сделать.
решение1
Я бы попробовал что-то вроде этого:
#!/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
Если в ваших файлах журналов содержится что-то большее, чем просто строки, разделенные пробелами, скрипт awk может нарушить форматирование.
решение2
Вам следует попробовать записать sed
шаблон в файл и передать его sed
с помощью параметра --file=
. Параметры командной строки не предназначены для передачи больших объемов данных.