LINUX.ORG.RU

Развернуть 1,3-5,8 в 1,3,4,5,8

 ,


1

2

Есть куча конфгов, примерно следующего содержания

config ports 2 state enable description user1 
config ports 6 state enable description user2 
config ports 7 state enable description user3 
config ports 1,3-5,8 state disable description clear
Мне нужно привести к виду:
ports 1 disable clear
ports 2 enable  user1 
ports 3 disable clear
ports 4 disable clear
ports 5 disable clear
ports 6 enable  user2 
ports 7 enable  user3 
ports 8 disable clear
Те развернуть 1,3-5,8 в 1,3,4,5,8 Сейчас делаю так:
cat cfg | awk '/config/{ 
ports[$3,1]=$5
ports[$3,2]=$7}
Но разумеется он не корректно переваривает 1,3-5,8. Как я полагаю нужно предварительно преобразовать строку «config ports 1,3-5,8 state disable description clear» в
config ports 1 state disable clear
config ports 3 state disable clear
config ports 4 state disable clear
config ports 5 state disable clear
config ports 8 state disable clear
но не могу придумать как преобразовать эту последовательность в массив? (что бы потом в awk использовать for ( i in array ) {}. Подскажите пожалуйста куда копать?


$ echo "config ports 2 state enable description user1
config ports 6 state enable description user2
config ports 7 state enable description user3
config ports 1,3-5,8 state disable description clear" | while read A B C REST ; do
  for D in ${C//,/ } ; do
    for E in $( seq ${D%%-*} ${D##*-} ) ; do
      echo "$A $B $E $REST";
    done;
  done;
done
Kroz ★★★★★ ()
Ответ на: комментарий от Kroz

Kroz, интересный вариант. но иногда встречается что то типа: «config ports 1,3-5,8-10,15» и никогда нельзя быть увереным что их только 2,3 или 4 части.

DeeZ ()
Ответ на: комментарий от DeeZ
$ unset RES_TOTAL; for PAT in `echo "1,3-5,8-10,15" | tr ',' ' '`; do  BEGIN=`echo $PAT | awk -F- '{print $1}'`; END=`echo $PAT | awk -F- '{print $2}'`; if [ -n "${END}" ]; then RES=`seq $BEGIN $END | xargs | tr ' ' ','`;  else RES=$PAT; fi; echo "$PAT -> $RES"; RES_TOTAL="${RES_TOTAL}${RES},"; done; echo "total: $RES_TOTAL"
1 -> 1
3-5 -> 3,4,5
8-10 -> 8,9,10
15 -> 15
total: 1,3,4,5,8,9,10,15,

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

anonymous ()
Ответ на: комментарий от DeeZ

никогда нельзя быть увереным что их только 2,3 или 4 части.

А у меня ограничения нет. Проверяй - работает и с 1,3-5,8-10,15 и с чем угодно подобным.
Я просто сам недавно для себя такое делал.

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

если не понятно что, то ты, возможно, ГСМ или вантузятник. что одно и то же.

mos ★★☆☆☆ ()
Ответ на: комментарий от Kroz

Kroz, :) ну в общем то почти да. За твой вариант тоже спасибо. его немного в другом месте применил.

DeeZ ()
#!/usr/bin/perl -ln

if (/config/) {
    ($a,$b,$c,$d) =/(ports) (.*) state (enable|disable) description (.*)/;
    map {print "$a $_ $c $d" for /^(.*\d)-(.+)$/ ? $1..$2 : $_} split /,/, $b;
}
$ parse.pl configs | sort -k2
Deleted ()
Ответ на: комментарий от Deleted

куда только смотрят модераторы. не запускайте это

anonymous ()
Ответ на: комментарий от Deleted

Ну ты чего блин такое творишь? Чуть не запустил...

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