Какой эффективный способ изменить огромный файл на месте - PullRequest
0 голосов
/ 12 мая 2019

У меня огромный файл (~ 2000000 строк), и я пытаюсь заменить несколько разных шаблонов, пока читаю файл только один раз.

так что я предполагаю, что sed не хорош, так как у меня разные модели я пытался использовать awk с if else, но файл не изменился

#!/usr/bin/awk -f
{

    if($0 ~ /data for AAA/)
    {

        sub(/^[0-9]+$/, "bla_AAA", $2)

    }
    if($0 ~ /data for BBB/)
    {

        sub(/^[0-9]+$/, "bla_BBB", $2)

    }


}

Я ожидаю выхода

address 01000 data for AAA
....
address 02000 data for BBB
....

будет

address bla_AAA data for AAA
....
address bla_BBB data for BBB
....

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Я не вижу никаких признаков в вашем вопросе, что ваш файл действительно имеет большой размер, так как 2000000 строк - это ничто, и каждая строка сэмпла в вашем вопросе мала, поэтому есть вероятность, что это все, что вам нужно:

awk '
/data for AAA/ { $2 = "bla_AAA"; next }
/data for BBB/ { $2 = "bla_BBB"; next }
' file > tmp && mv tmp file

GNU awk имеет опцию -i inplace для того же типа редактирования "на месте", что и sed, perl и т. Д. (Т. Е. Для внутреннего использования файла tmp).

Если вы действительно этого не сделалиу вас недостаточно места для создания копии входного файла, тогда вы можете использовать что-то вроде этого (не проверено!):

headLines=10000
beg=1
tmp=$(mktemp) || exit 1
while -s file; do
    head -n "$headLines" file | awk 'above script' >> "$tmp" &&
    headBytes=$(head -n "$headLines" file |wc -c) &&
    dd if=file bs="$headBytes" skip=1 conv=notrunc of=file &&
    truncate -s "-$headBytes" file
    rslt=$?
done
(( rslt == 0 )) && mv "$tmp" file

, поэтому вы никогда не используете больше памяти, чем размер вашего входного файла, плюсheadLines строк (массируйте это число, чтобы удовлетворить).См. https://stackoverflow.com/a/17331179/1745001 для получения информации о том, что truncate и 2 строки перед этим делают.

0 голосов
/ 12 мая 2019

Примерно так:

(чтение строки, манипулирование текстом, запись измененных данных в выходной файл)

with open('in.txt') as f_in:
    with open('out.txt', 'w') as f_out:
        line = f_in.readline().strip()
        while line:
            fields = line.split(' ')
            fields[1] = 'bla_{}'.format(fields[4])
            f_out.write(' '.join(fields) + '\n')
            line = f_in.readline()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...