замена более 6000 строк в текстовом файле> 2 ГБ

350
HansPeter

Я хотел бы найти и заменить более 6000 строк в текстовом файле> 2 ГБ.

sed -i "s/search/replace/g" 2gbfile.log 

принимает навсегда. Особенно, если вам нужно сделать это более 6000 раз.

Поэтому я разработал сценарий, который разбивает файл размером 2 ГБ на куски, чтобы можно было распараллелить усилия. Я запускаю 48 процессов одновременно (доступно 64 ядра), но все же это занимает довольно много времени.

#!/usr/bin/env bash  echo "sorting..." sort bigbigbigfile | awk -F, '' > bigbigbigfile.work  CPUS=$(( $(lscpu |grep "On-line CPU(s) list"|grep -Eo '0-[0-9]+'|cut -f2 -d-) + 1)) CPUSUSABLE=$(echo "$CPUS*0.75" | bc | cut -f1 -d.) NUMLINES=$(cat all-temperatures.sort | wc -l) SPLIT=$(echo "$NUMLINES / $CPUSUSABLE" | bc | cut -f1 -d.) echo "cutting..." split -l $SPLIT bigbigbigfile.work chunkstoworkwith  mapfile -t REPLACEME < replace.list  echo "seding..." for chunk in $(ls chunkstoworkwith*); do ( for i in "${!REPLACEME[@]}"; do counter=$(( counter + 1 )) sed -i "s/ $ / $counter /g" $chunk done ) & done 

Это работает. Но я думаю, что это может быть даже быстрее, когда я ищу и заменяю в памяти, вместо того, чтобы делать замену на месте и делать 6000+ замен в 48 файлах. Это суммирует почти 300 тыс. Вызовов sed, что приводит к большому количеству открытия / закрытия / записи / чего угодно файла.

Любая идея о том, как ускорить это и сделать замены в памяти и сброс данных после того, как все было изменено?

0
HI HansPeter. Добро пожаловать в SuperUser. Казалось бы, на этот вопрос лучше ответить в StackOverflow, а не в SuperUser, поскольку в нем задействован сценарий Bash. ты задал этот вопрос там? Stese 6 лет назад 0
Нет, нет, нет. Сделаю. Благодарю. HansPeter 6 лет назад 0
[Несколько операций поиска и замены в одном большом текстовом файле] (https://superuser.com/q/618407/241386), [Замена нескольких строк в нескольких файлах] (https://stackoverflow.com/q/51608196/995714 ), [Быстрая замена текста в очень большом файле] (https://unix.stackexchange.com/q/255373/44425), [Замена нескольких строк в большом текстовом файле в Python] (https://stackoverflow.com/ д / 41192945/995714) phuclv 6 лет назад 0

2 ответа на вопрос

2
oliv

Ваш скрипт анализирует весь кусок для каждой замены!

Это означает, что для каждого блока открывается сценарий, проходит все строки, возможно, выполняет 1 замену, закрывает файл и перемещает его в исходный файл (из-за -iопции).

При условии, что вы хотите заменить шаблон счетным числом, вот способ выполнить все замены сразу для каждого блока:

sed -f <(awk '' replace.list) -i "$chunk" 

-fОпция позволяет принимать SED сценария в качестве входных данных и будет выполняться сразу для всех строк $chunkфайла.

Это, вероятно, уменьшит общее время ...

Согласовано. Первое улучшение - сделать все замены в одном файле доступа. xenoid 6 лет назад 0
Великолепно, спасибо! HansPeter 6 лет назад 0
0
Xen2050

Я не совсем уверен, почему ваш sed идет так медленно, вам, вероятно, придется отлаживать или смотреть его поближе, чтобы действительно выяснить, но если он пытается написать 6000 раз и это замедляет работу, вы можете пропустить -iи просто sed записал весь (измененный) файл один раз:

sed "s/search/replace/g" 2gbfile.log > 2bgfile-AfterSed.log 
Это также потребовало бы 6000 вызовов sed (для каждого шаблона, который требует замены), и его нельзя распараллелить. HansPeter 6 лет назад 0
Сед работает только один раз, читает один раз и пишет один раз, и я предполагаю, что это может быть запись на месте, которая настолько медленная. Как долго длится этот метод? Xen2050 6 лет назад 0
`$ time sed" s / search / replace / g "2gbfile.log> 2bgfile-AfterSed.log #real 0m18.451s` HansPeter 6 лет назад 0
(18 * 6000) / 3600 = 30 часов. HansPeter 6 лет назад 0
Это только на 1/6000 от файла 2 ГБ. Во всяком случае, не зная, где находится узкое место, мы просто догадываемся, обычно чтение и запись выполняются намного медленнее, чем любые вычисления, такие как простой поиск / замена. Xen2050 6 лет назад 0
вероятно, передача результата в следующий sed будет быстрее, чем сохранение промежуточного результата в файл. Однако я думаю, что для этого нужно специализированное решение, так как нет общих инструментов для замены такого огромного количества строк в большом файле. phuclv 6 лет назад 0