У меня есть большое количество файлов журналов, на 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 файлами в каждом каталоге, чтобы пройти через. Чем больше клиентских файлов я создаю, тем больше проходов я должен сделать.

2 ответа2

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 может нарушить форматирование.

0

Вы должны попытаться записать шаблон sed в файл и передать его sed с параметром --file= . Параметры командной строки не предназначены для передачи больших кусков данных.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .