Команда Linux для замены строки в файле LARGE другой строкой - PullRequest
8 голосов
/ 07 августа 2009

У меня есть огромный файл SQL, который выполняется на сервере. Дамп с моей машины, и в нем есть несколько настроек, относящихся к моей машине. В общем, я хочу, чтобы каждое вхождение "c://temp" было заменено на "//home//some//blah"

Как это можно сделать из командной строки?

Ответы [ 7 ]

29 голосов
/ 07 августа 2009

sed - хороший выбор для больших файлов.

sed -i.bak -e 's%C://temp%//home//some//blah%' large_file.sql

Это хороший выбор, потому что не читает весь файл сразу, чтобы изменить его. Цитирую руководство:

Для выполнения используется потоковый редактор. основные преобразования текста на входе поток (файл или вход из трубопровод). Хотя в чем-то похожи редактору, который разрешает сценарий редактирует (например, ed), sed работает делая только один проход через вход (ы), и, следовательно, больше эффективный. Но это способность Седа фильтровать текст в конвейере, который особенно отличает его от другие типы редакторов.

Соответствующий раздел руководства здесь . Небольшое объяснение следует

-i.bak включает редактирование на месте, оставляя резервную копию с расширением .bak

s% foo% bar% использует s, команду подстановки, которая заменяет совпадения первой строки между знаком%, 'foo', для второго строка, 'бар'. Обычно пишется как s // а потому что в твоих струнах много косых черт, удобнее изменить их на что-то другое, чтобы вы избегать необходимости избегать их.

* * Пример тысяча двадцать-одина * * тысяча двадцать-дв
vinko@mithril:~$ sed -i.bak -e 's%C://temp%//home//some//blah%' a.txt
vinko@mithril:~$ more a.txt
//home//some//blah
D://temp
//home//some//blah
D://temp
vinko@mithril:~$ more a.txt.bak
C://temp
D://temp
C://temp
D://temp
12 голосов
/ 07 августа 2009

Просто для полноты. Замена на месте с использованием perl.

perl -i -p -e 's{c://temp}{//home//some//blah}g' mysql.dmp

Также не требуется экранирование от обратной косой черты. ;)

4 голосов
/ 07 августа 2009

Попробуйте Сед ? Что-то вроде:

sed 's/c:\/\/temp/\/\/home\/\/some\/\/blah/' mydump.sql > fixeddump.sql

Если убрать все эти косые черты, это выглядит ужасно, вот простой пример, который заменяет foo на bar.

sed 's/foo/bar/' mydump.sql > fixeddump.sql

Как уже отмечали другие, вы можете выбрать свой собственный разделитель, который предотвратит синдром наклоняющейся зубочистки в этом случае:

sed 's|c://temp\\|home//some//blah|' mydump.sql > fixeddump.sql

Самое умное в sed - это то, что он работает с потоком , а не с файлом одновременно, поэтому вы можете обрабатывать огромные файлы, используя только скромный объем памяти.

3 голосов
/ 07 августа 2009

Существует также нестандартная утилита UNIX, rpl , которая делает то же самое, что и примеры sed; однако я не уверен, работает ли rpl по потоку, так что sed может быть лучшим вариантом здесь.

1 голос
/ 07 августа 2009

простак

awk '{gsub("c://temp","//home//some//blah")}1' file
1 голос
/ 07 августа 2009
perl -pi -e 's#c://temp#//home//some//blah#g' yourfilename

-p будет рассматривать этот скрипт как цикл, он будет читать указанный файл построчно, выполняя поиск и замену регулярного выражения.

-i Этот флаг следует использовать вместе с флагом -p. Это команды Perl для редактирования файла на месте.

-e Просто означает выполнить этот код Perl.

Удачи

1 голос
/ 07 августа 2009

Команда sed может сделать это. Вместо того, чтобы избегать косых черт, вы можете выбрать другой разделитель (_ в данном случае):

sed -e 's_c://temp/_/home//some//blah/_' file1.txt > file2.txt
...