LINUX.ORG.RU

Как отредактировать только часть файла и не трогать остальную?

 


0

1

Есть гигантских размеров (порядка 125 Гб) текстовый файл, в первых 1000 строках которого нужно сделать замену, не перезаписывая остальные 10^9 или сколько там строк.
Вопрос: как это сделать sed'ом, а если не sed'ом, то чем?
Дело в том, что sed, судя по всему, в режиме -i тупо копирует файл строка за строкой, а под конец «магически» заменяет старый файл новым. Соответственно, если в sed сделать q, то файл оборвётся на той строке, на которой был сделан q, а если q не делать, то придётся ждать до посинения, пока sed героически перезапишет 150Гб на диске. Ну ок, предположим, что для дозаписи данных (а именно это, к сожалению, мне и нужно), так или иначе всё равно придётся перекорячить весь файл, но вот а если бы мне нужно было, скажем, символ B на символ А в первых 200-ах строках поменять - ведь для этого очевидным образом перезапись всего файла не требуется: достаточно лишь прочитать первые 200 строк и поменять один байтик на другой...

★★★★★

Думаю, такое можно провернуть в питоне с модулем mmap. в детали сейчас вникать не могу, слишком занят.

anonymous
()
Ответ на: комментарий от NeXTSTEP

код на перле … 125 Гб … код на перле … 125 Гб … МАМА! Мне это даже представить страшно… o_O

Таки откусить кусок с начала dd, поправить его и прицепить обратно. Ещё как вариант — задействовать ed.

beastie ★★★★★
()

Я бы на перле простым скриптиком читал бы файл построчно и менял то, что там надо. Там это легко делается без занесения в память всего файла.

shell-script ★★★★★
()
Ответ на: комментарий от shell-script

Ты представляешь, сколько оно его шустприть будет?

Говорят vim с LargeFile плагином может такого монстра осилить. → http://stackoverflow.com/questions/1591723/linux-text-editor-for-working-with...

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от sdio

если замена не меняет размер, то можно dd+sed+dd

угу. Тоже хотел написать.

emulek
()

Дело в том, что sed, судя по всему, в режиме -i тупо копирует файл строка за строкой, а под конец «магически» заменяет старый файл новым.

так и есть. Это ещё и самый быстрый вариант, т.к. размер начала изменяется, и файл всё равно надо весь переписывать. Если не надо, то отрежь dd нужное.

emulek
()

ведь для этого очевидным образом перезапись всего файла не требуется

Только в этом одном случае (поменять N символов на N других), только если количество байтов на эти символы в данной кодировке совпадает, это необходимо только если у тебя откуда-то возник текстовый файл на 125 Гб... Короче, множество предположений, которые в 99.99% случаев неверны.

Может, написать свой велосипед на каком-нибудь языке программирования? В конце концов, это не так сложно. python + mmap, в самом деле.

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 2)
Ответ на: комментарий от kovrik

Вообще, сама задача странная какая-то.

Почему странная? Есть гигантский SQL dump и в нём нужно поправить всего-то пару определений create table. Причём дамп размером 150Гб лежит на разделе размером 200Гб и никаких других разделов не предусмотрено. Что делать?

Я пока что решил проблему с помощью sed'а для копирования «верхушки» файла в отдельный файл и tail -n +N - для оставшейся части. В принципе, так работает, но только для случая, когда интересующие строки находятся в относительно небольшом куске файла где-то «на самом верху».
Кстати, кто-нибудь в курсе, как сделаьт так, чтобы чудесный mysqldump всё-таки свои CREATE TABLE писал не где-то посреди INSERT'ов, а сверху? Мне для этого пришлось изрядно поизвращаться и написать целый мега-скрипт... Вот: https://github.com/DRVTiny/bash4-helperScripts/blob/master/dumeme

DRVTiny ★★★★★
() автор топика
Последнее исправление: DRVTiny (всего исправлений: 1)
Ответ на: комментарий от DRVTiny

Есть гигантский SQL dump

А, ну это еще норм, я уже думал XML

goingUp ★★★★★
()
Ответ на: комментарий от beastie

Так в условии ТС надо прошерстить тысячу строк вначале файла. Это вообще ни о чём. Секунды.

P.S. за плагинчик к vim'у спасибо, думаю пригодится.

shell-script ★★★★★
()
Ответ на: комментарий от DRVTiny

Можно сделать два дампа.

Первый mysqldump --no-data, тут будет структура. Второй mysqldump --no-create-info, тут данные. По желанию, их можно потом объединить.

Ну или же вообще можно каждую таблицу в отдельный файл.

shell-script ★★★★★
()
Ответ на: комментарий от MikeDM

Это непартиционированная база, куда Заббикс интенсивно пишет всякий мусор, который ни один человек в здравом уме и твёрдой памяти проанализировать не в состоянии. Сейчас стоит задача мусор этот партиционировать.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

mysqldump умеет писать данные каждой таблички в отдельный файл. В случае таких огромных дампов, наверное, имеет смысл.

undertaker ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.