Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Скрипт парсинга traceroute  (Прочитано 891 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн sashk0

  • Автор темы
  • Новичок
  • *
  • Сообщений: 47
    • Просмотр профиля
Скрипт парсинга traceroute
« : 03 Февраль 2014, 21:07:59 »
Доброго времени суток!

Что-то я немного запутался, с синтаксисом shell ещё только знакомлюсь. Пишу скрипт, который парсит пару трасеров
traceroute to 195.19.160.1 (195.19.160.1), 64 hops max, 52 byte packets
 1  192.168.0.1 (192.168.0.1)  0.385 ms  0.229 ms  0.193 ms
 2  195.19.161.100 (195.19.161.100)  0.715 ms  0.860 ms  0.740 ms
 3  ats-sw4-vl509.pu.ac.ru (195.19.164.108)  0.844 ms  0.802 ms  0.834 ms
 4  serv1.pu.ac.ru (195.19.160.1)  0.918 ms  0.584 ms  0.564 ms

traceroute to ya.ru (213.180.204.3), 64 hops max, 52 byte packets
 1  192.168.0.1 (192.168.0.1)  0.381 ms  0.222 ms  0.208 ms
 2  195.19.161.100 (195.19.161.100)  0.701 ms  0.948 ms  0.726 ms
 3  ats-sw4-vl509.pu.ac.ru (195.19.164.108)  0.832 ms  0.851 ms  0.787 ms
 4  ats-gw2-f1.0.30.pu.ru (195.19.176.65)  0.754 ms  0.580 ms  0.601 ms
 5  ats-gw1.pu.ru (195.19.164.69)  0.763 ms  0.850 ms  0.724 ms

И приводит их к виду:
"192.168.0.1" -> "195.19.161.100" [ label = "0.740 ms" ]
 "195.19.161.100" -> "195.19.164.108" [ label = "0.834 ms" ]
 "195.19.164.108" -> "195.19.160.1" [ label = "0.564 ms" ]
 "195.19.164.108" -> "195.19.176.65" [ label = "0.601 ms" ]
 "195.19.176.65" -> "195.19.164.69" [ label = "0.724 ms" ]

Не знаю как правильно дальше сделать, либо через цикл, либо через регулярки как-то можно это сделать.
Вот что я сделал(сохранил трасеры в текстовый файл, чтобы не дергать каждый раз):
cat tr.txt | grep -v '^[a-z]' | grep -v '*' | sed -r '/^$/d' | sed 's/(//g' | sed 's/)//g' | awk '{print ""$3" [ label = \""$8" ms\" ]"}'
И добился вот такого вида:
192.168.0.1 [ label = "0.193 ms" ]
195.19.161.100 [ label = "0.740 ms" ]
195.19.164.108 [ label = "0.834 ms" ]
195.19.160.1 [ label = "0.564 ms "]
192.168.0.1 [ label = "0.208 ms" ]
195.19.161.100 [ label = "0.726 ms" ]
195.19.164.108 [ label = "0.787 ms" ]
195.19.176.65 [ label = "0.601 ms" ]
195.19.164.69 [ label = "0.724 ms" ]

Подскажите, что дальше? Или я вообще по тупиковому пути пошел?

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4073
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #1 : 03 Февраль 2014, 21:54:43 »
Что-то я немного запутался, с синтаксисом shell ещё только знакомлюсь.
Как вариант использовать язык, который знаешь ;) Есть python, уроки рядом.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн sashk0

  • Автор темы
  • Новичок
  • *
  • Сообщений: 47
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #2 : 03 Февраль 2014, 22:10:07 »
alsoijw,
Это не вариант, я могу сделать на другом языке, но я хочу сделать это средствами баша :)

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4073
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #3 : 03 Февраль 2014, 22:25:48 »
Какие аргументы передаются первой команде?
для каждого адреса преобразованного в параметр
    запустить программу с аргументом
    получить вывод, подставив аргумент
    добавить в файл
готово
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5631
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #4 : 03 Февраль 2014, 22:28:40 »
Через цикл, потому как sed|awk строковые редакторы. Можно строки объединять, но это не вариант. А так берете из первой строки переменную адрес и время, из второй адрес и формируете вывод и дальше в цикл.
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн sashk0

  • Автор темы
  • Новичок
  • *
  • Сообщений: 47
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #5 : 03 Февраль 2014, 22:38:20 »
Так я и понял, через цикл значит всё-таки.
Хотя, нашёл тут вариант не использовать цикл http://stackoverflow.com/questions/6426142/to-append-each-element-fo-a-string-array-in-bash
array=(a b c d e)
array=( "${array[@]/%/_content}" )
printf '%s\n' "${array[@]}"


Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5631
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #6 : 03 Февраль 2014, 23:27:56 »
Даже если объявлять двумерный массив… всё равно через цикл объединять а1 с а2, а2 с а3…
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн sashk0

  • Автор темы
  • Новичок
  • *
  • Сообщений: 47
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #7 : 04 Февраль 2014, 00:04:00 »
Задачу решил через один массив, правда с выводом на консоль, но ничто не мешает сохранить в другое место.
Выкладываю на суд, дабы не быть голословным. Может кому и пригодится, хоть решение и не самое лучшее, на мой взгляд.
aaa=(`cat tracert.txt | grep -v '^[a-z]' | grep -v '*' | sed 's/(//g' | sed 's/)//g' | awk '{print ""$3" "$8""}'`)
cnt=${#aaa[@]}
for ((i=0;i<cnt-2;i++)); do
  if [ $i -eq $((i/2*2)) ]; then
    echo "\"${aaa[i]}\" -> \"${aaa[i+2]}\" [ label = \"${aaa[i+3]}\" ]"
  fi
done

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5631
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #8 : 04 Февраль 2014, 01:55:28 »
А я бы делал 2 массива: 1-й с адресами, второй с временем и вывод был бы проще aaa[i] --> aaa[i+1] label = bbb[i]
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн sashk0

  • Автор темы
  • Новичок
  • *
  • Сообщений: 47
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #9 : 04 Февраль 2014, 03:07:27 »
Azure,
Не спорю, возможно, я так и сделал бы, но у меня уже часть реализована была, поэтому выбрал этот способ.

Оффлайн victor00000

  • Старожил
  • *
  • Сообщений: 14866
  • Я не слышу.
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #10 : 04 Февраль 2014, 05:20:36 »
diff 1day.txt 2day.txt > ok.txt
~.o

Оффлайн golota

  • Участник
  • *
  • Сообщений: 132
    • Просмотр профиля
Re: Скрипт парсинга traceroute
« Ответ #11 : 05 Февраль 2014, 23:27:11 »
aaa=(`cat tracert.txt | grep -v '^[a-z]' | grep -v '*' | sed 's/(//g' | sed 's/)//g' | awk '{print ""$3" "$8""}'`)
cnt=${#aaa[@]}
for ((i=0;i<cnt-2;i++)); do
  if [ $i -eq $((i/2*2)) ]; then
    echo "\"${aaa[i]}\" -> \"${aaa[i+2]}\" [ label = \"${aaa[i+3]}\" ]"
  fi
done
5 пайпов и bash, легко меняются на 1 awk
Следующий код, сохраняем в файл tm.awk
BEGIN { n=1;}
!/^[a-z]|\*/  { if (length($0)>1) {gsub(/[\)\(]/,"") ; ip[n]=$3; ms[n]=$8; n++} } 
END { for (x=1;x<n-1;x++) print "\"" ip[x] "\" -> \"" ip[x+1] "\" [ label = \"" ms[x+1] "\" ]"}
и запускаем - awk -f tm.awk tracert.txt
Можно обойтись без .awk файла и влепить всё в коммандную строку. Но мне так больше нравится  :coolsmiley:

Проверяем скорость работы -
(Нажмите, чтобы показать/скрыть)
Итого: awk сработал примерно в 7 раз быстрее ...

Простые задачи, просто решаются с awk, и быстро работают.
Советую почитать GNU Awk User's Guide жить станет легче и веселей  ;)
Если задача посложнее, тогда можно думать о perl,python или php и.т.д.
Часто, сама задача подскзывает, на каком языке лучше её решать  ;)

Интересный факт, обычно комманды Unix несут смысловую нагрузку и расшифровывают её назначение.
Фактически единственное исключение это AWK, от фамилий разработчиков (Aho, Weinberg, Kernigan)
« Последнее редактирование: 06 Февраль 2014, 01:43:58 от golota »
Я знаю то, что ничего не знаю, но некоторые не знают и этого. Сократ

 

Страница сгенерирована за 0.064 секунд. Запросов: 24.