Потоковое редактирование на месте с помощью ed
Для того что бы заменить строчку в файле часто используется sed с ключиком -i.
Но не все знают что sed на самом деле создает копию файла и заменяет его на оригинал (не лишнее будет прочитать в man sed что на самом деле обозначает -i).
Проверить это можно так:
$ echo 1 > z.txt && ls -li z.txt && sed -i 'i1' z.txt && ls -li z.txt && rm z.txt 5290353 -rw-rw-r-- 1 ramok ramok 2 Апр 7 13:00 z.txt 5290354 -rw-rw-r-- 1 ramok ramok 4 Апр 7 13:00 z.txt
Здесь создается пустой текстовый файл, выводится номер его inode, затем с помощью sed добавляется '1', и снова выводится inode файла.
Видно что inode изменился.
При этом копия файла создается в текущей директории. Увидеть это можно так:
$ echo 1 > z.txt && ls -li z.txt && strace sed -i 'i1' z.txt 2>&1 | grep open && ls -li z.txt && rm z.txt 879149 -rw-rw-r-- 1 komar komar 2 Апр 7 13:06 z.txt open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib/libselinux.so.1", O_RDONLY) = 3 open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3 open("/lib/i686/cmov/libdl.so.2", O_RDONLY) = 3 open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3 open("//lib/charset.alias", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = 3 open("z.txt", O_RDONLY|O_LARGEFILE) = 3 open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 4 open("./sed3H2GOp", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4 5290353 -rw-rw-r-- 1 komar komar 4 Апр 7 13:06 z.txt
Это обозначает что иногда могу возникнуть проблемы если недостаточно места на диске для создания копии файла или вы не имеете право создавать файлы в текущей директории. Так же это не сработает если вы хотите изменить что то в виртуальных файлах в файловой системе /proc и /sys.
Так же если файл большой, то может существенно тормозить, что плохо подходит для больших лог файлов.
Поэтому не рекомендуется пользоватся sed таким образом. Хотя все это делают Ж:-)
Решение в лоб - создавать копию файла явно и затем заменять с проверкой все ли закончилось удачно.
Еще одно решение - использовать прорадителя sed, текстовый редактор ed.
$ echo 1 > z.txt && ls -li z.txt && ed -s z.txt <<<$'i\n1\n.\nwq\n' && ls -li z.txt && rm z.txt 5290353 -rw-rw-r-- 1 ramok ramok 2 Апр 7 13:00 z.txt 5290353 -rw-rw-r-- 1 ramok ramok 4 Апр 7 13:00 z.txt
Тут ed делает тоже самое что и sed в примере выше (добляет '1' после каждой строчки).
Видно что inode не изменился.
- 1279 просмотров
Страница для печати


perl -p -i -e 's/чтоищем/начтоменяем/g' file
не проще ли?
а проверить не пробовал? не проще
$ echo 1 > z.txt && ls -li z.txt && perl -pi -e 'print "$_"' z.txt && ls -li z.txt && rm z.txt 5290359 -rw-rw-r-- 1 ramok ramok 2 Апр 8 19:32 z.txt 5290379 -rw-rw-r-- 1 ramok ramok 4 Апр 8 19:32 z.txtтаже песня что и с sed
Отправить комментарий