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

しかし、今、私たちの部署の1つからCLIENT_FILE.txtが送られてきました。425000+変数です!内部制限に達した可能性があります。これほど多くの変数を処理する方法についてアイデアをお持ちの方がいらっしゃいましたら、ぜひ教えてください。

クライアント ファイルを 4 つに分割して、それぞれに約 100,000 個の変数を持たせようとしましたが、それでもうまくいきません。ただし、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=。コマンドラインパラメータは、大量のデータを渡すためのものではありません。

関連情報