我在 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=
。命令行参数不是为了传递大量数据。