使用 sed 替换文件中的大量变量

使用 sed 替换文件中的大量变量

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

相关内容