[Решено] Замена , на . в текстовом файле размером 300 метров в bash?

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
slackman
Сообщения: 49
ОС: OpenSuse 11.1

[Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение slackman »

Всем привет!

Нужна Ваша помощь... На работе под виндами.... есть необходимость заменить , на . во всем текстовом файле... файл весит 300 метров.... Вообще загонял в акссесс (нужно было), но там размер буфера на замену ой ой маловат... На компах нельзя ставить far.... вот сейчас из дому пишу... стоит слака... Как можно решить задачу через bash? Возможны ли решения под линукс чтобы быстрее было... по скорости обработки... файлов штук 5-6. ))))

Спасибо!
Спасибо сказали:
Аватара пользователя
Goodvin
Ведущий рубрики
Сообщения: 4333
Статус: ⚝⚠⚒⚑⚖☭☞☣☤&

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение Goodvin »

Попробуйте sed
Спасибо сказали:
Аватара пользователя
Vasily_Shmelyov
Сообщения: 88
ОС: Ubuntu

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение Vasily_Shmelyov »

Код: Выделить всё

vzhik@lilith-pc:~$ echo 'fff,fffff,ghggggh,hhhh,kkk,,,kk,k,,,k' | tr , .
fff.fffff.ghggggh.hhhh.kkk...kk.k...k

Вот в таком аксепте :)
The pessimist says the glass is half empty.
The optimist says the glass is half full.
The engineer says the container is twice as large as it needs to be.
The physicist says the glass is neither. It is completely full, half with water, the other half with air.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение diesel »

slackman писал(а):
09.02.2009 21:11
Всем привет!

Нужна Ваша помощь... На работе под виндами.... есть необходимость заменить , на . во всем текстовом файле... файл весит 300 метров.... Вообще загонял в акссесс (нужно было), но там размер буфера на замену ой ой маловат... На компах нельзя ставить far.... вот сейчас из дому пишу... стоит слака... Как можно решить задачу через bash? Возможны ли решения под линукс чтобы быстрее было... по скорости обработки... файлов штук 5-6. ))))

Спасибо!


sed -i -e 's!,!.!g' filename
perl -i -p -e 's!,!.!g' filename
Спасибо сказали:
Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение rm_ »

Vasily_Shmelyov правильно подметил, достаточно tr, и кроме того, сработает она в разы быстрее sed или perl.
Спасибо сказали:
Аватара пользователя
slackman
Сообщения: 49
ОС: OpenSuse 11.1

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение slackman »

Решено. Спс всем!
tr хорош... )))
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение diesel »

rm_ писал(а):
09.02.2009 23:20
Vasily_Shmelyov правильно подметил, достаточно tr, и кроме того, сработает она в разы быстрее sed или perl.

на 300-метровом файле? 300 метров не хочу искать, взял вот такой:

Код: Выделить всё

diesel@indie:/tmp$ wc -l file
   54846 file
diesel@indie:/tmp$ ls -lh file
-rw-r--r--  1 diesel  staff   4.9M Feb 10 10:47 file

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

Код: Выделить всё

diesel@indie:/tmp$ time cat file | tr : , > file.new

real    0m0.683s
user    0m0.491s
sys    0m0.045s
diesel@indie:/tmp$ time sed -i.bak -e 's!:!,!g' file

real    0m0.571s
user    0m0.374s
sys    0m0.043s
diesel@indie:/tmp$ cp file.bak file
diesel@indie:/tmp$ time perl -p -i.bak -e 's!:!,!g' file

real    0m0.418s
user    0m0.172s
sys    0m0.046s

Если неделать бэкапа:

Код: Выделить всё

diesel@indie:/tmp$ cp file.bak file
diesel@indie:/tmp$ time perl -p -i -e 's!:!,!g' file

real    0m0.369s
user    0m0.168s
sys    0m0.045s
diesel@indie:/tmp$ cp file.bak file
diesel@indie:/tmp$ time sed -i.bak -e 's!:!,!g' file

real    0m0.531s
user    0m0.382s
sys    0m0.045s
diesel@indie:/tmp$ cp file.bak file
diesel@indie:/tmp$ time cat file | tr : , > file.new

real    0m0.697s
user    0m0.493s
sys    0m0.045s


на 300 метрах cat file |tr > file.new будет тормозить больше
PS: интересно увидеть time для всех операций на задаче топикстартера
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение drBatty »

rm_ писал(а):
09.02.2009 23:20
правильно подметил, достаточно tr, и кроме того, сработает она в разы быстрее sed или perl.

если файл лежит в памяти и новый пишется туда-же, то да. Но, такой файл лежит на диске, потому, его ещё с диска надо прочитать, что:
1) выполнится намного дольше чем tr, se, perl...
2) выполнится параллельно с tr, sed, perl...
потому разницы НЕ будет.
особенно это заметно, если файл настолько большой, что не влазит в RAM, тогда его ещё и сохранить надо...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение ZyX »

drBatty писал(а):
05.03.2010 20:41
rm_ писал(а):
09.02.2009 23:20
правильно подметил, достаточно tr, и кроме того, сработает она в разы быстрее sed или perl.

если файл лежит в памяти и новый пишется туда-же, то да. Но, такой файл лежит на диске, потому, его ещё с диска надо прочитать, что:
1) выполнится намного дольше чем tr, se, perl...
2) выполнится параллельно с tr, sed, perl...
потому разницы НЕ будет.
особенно это заметно, если файл настолько большой, что не влазит в RAM, тогда его ещё и сохранить надо...

Замерил у себя:

Код: Выделить всё

(zyx:~/tmp) % dd if=/dev/urandom of=randomfile bs=1024 count=$((300*1024))
307200+0 записей считано
307200+0 записей написано
 скопировано 314572800 байт (315 MB), 97,1064 c, 3,2 MB/c
(zyx:~/tmp) % su -c 'echo 1>/proc/sys/vm/drop_caches'
Пароль:
(zyx:~/tmp) % time (cat randomfile|tr , .>/dev/null)
(; cat randomfile | tr , . > /dev/null; )  0,79s user 0,03s system 8% cpu 9,953 total
(zyx:~/tmp) % su -c 'echo 1>/proc/sys/vm/drop_caches'
Пароль:
(zyx:~/tmp) % time (cat randomfile|sed -e 's/\./,/g'>/dev/null)
(; cat randomfile | sed -e 's/\./,/g' > /dev/null; )  3,43s user 0,15s system 36% cpu 9,855 total
(zyx:~/tmp) % su -c 'echo 1>/proc/sys/vm/drop_caches'
Пароль:
(zyx:~/tmp) % time (cat randomfile|perl -p -i -e 's/\./,/g'>/dev/null)
(; cat randomfile | perl -p -i -e 's/\./,/g' > /dev/null; )  4,44s user 0,21s system 45% cpu 10,210 total

Насчёт узости IO вы правы. Но tr всё-таки быстрее.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: [Решено] Замена , на . в текстовом файле размером 300 метров в bash?

Сообщение drBatty »

ZyX писал(а):
12.03.2010 22:00
Замерил у себя:

спасибо. сначала не понял, откуда такая разница? потом понял - я использовал обычный живой текст написанный людьми, а вы использовали urandom. sed и perl оптимизированы для работы именно с текстом, и плохо работают с чем-то иным. во первых приходится грузить построчно, а размер строки у вас непонятно какой (средний - 256, но это только среднее значение. Кроме того, в тексте даже строки в 256байт - редкость, обычно меньше). Кроме того, была-ли у вас включена поддержка UTF? обычно она включена для sed, что приводит к уменьшению быстродействия ещё в полтора-два раза (особенно для мусора, где половина символов некорректные).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: