LINUX.ORG.RU

Почему-то очень тяжелый bash скрипт

 , ,


0

2

Я пишу SHELL скрипт, для более удобного чтения RSS/Atom

В нем есть вот такой фрагмент кода, который парсит строки из файла и занимается делами с каждой конкретной строкой:

i=1
while [ $i -lt "$(($(echo "$url" | wc -l)+1))" ]; do
	curl="$(cat file | head -n$i | tail -n1))"
	cache="$(echo "$cache"; echo "$curl" | sfeed | iconv -f "$(echo $curl | grep -o "<?xml.*?>" | grep -o "encoding=\".*\"" | grep -o "\".*\"")" -t UTF-8 | sfeed_plain)"
	i=$(($i+1))
done

Почему так долго - очевидно, если провернуть тоже самое в оболочке, то echo $cache займет примерно: real 0m3.365s user 0m3.220s sys 0m0.096s

что мучительно долго.

Но вот вопрос: чисто ради интереса попробовал после тех же действий printf $cache, и все вывелось за секунду, но когда я заменил в скрипте echo $cache на printf «$cache\n» стало как будто еще дольше.

P.s. Я понимаю, что тут уместнее использовать массивы, но это не стало решением

Тут много вопросов о не оптимальном программировании, но мне лень

вот к примеру в while на каждом шаге считается одна и таже константа

«$(($(echo «$url» | wc -l)+1))»

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

Починилось же. Теперь вычисляется один раз до цикла.

futurama ★★★★★
()

А скажите честно, кто писал ЭТО? Это надо быть больным на голову, чтобы так писать. Только для примера:

while read curl; do
    cache= # тут хрен знает что делает, так как вызываются явно локальные функции
done < "$url"
Эти дурацкие последовательные grep-ы вместо одного sed-а, тупые ненужные cat-ы и echo... Ну буквально каждое слово вашего скрипта применено совершенно в извращенной парадигме.

vodz ★★★★★
()

Программист на фортране на любом языке напишет на фортране (c)

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

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

Да хотя бы вот так:

dm@thinkpad:/tmp$ cat urls.txt 
http://foo.org
http://bar.net
http://baz.com
dm@thinkpad:/tmp$ cat urls.txt | while read url; do
> echo $url;
> done
http://foo.org
http://bar.net
http://baz.com

Между do и done ставишь своё тело. Ещё нет смысла конкатенировать вывод в одну и ту же переменную, это крайне неэффективно - вместо этого просто выводи выхлоп в поток как есть, а с этим потоком уже делай что тебе надо (парсь, пиши в файл, итп)

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