2015-01-07 5 views
0

у меня есть текстовый файл я генерировать с помощью Баш скрипт из различных crontabs сервера, который выглядит как этот формат:Как форматировать входной файл в bash в специальном формате?

0 SYS1 server1

5 sys2 server2

2,3 sys3

0 sys3 server3

7 sys4 server4

....

И я хочу, чтобы отформатированный к этому:

0 SYS1 server1

5 sys2 SERVER2

2 sys3 сервер3

3 sys3 server3

0 sys3 server3

7 sys4 сервера4

....

У меня есть проблема в том, что я его всегда можно изменить, если есть два числа на SYS/сервер или более, и там может быть также более две записи crontab для каждого сервера.

Мой attemp было что-то вроде этого:

rday_old="" 
    rsys_old="" 
    rser_old="" 
    [[ -e output ]] && rm output 
    while read -u5 -r -a line; do 
      rday=${line[0]} 
      rsys=${line[1]} 
      rser=${line[2]} 
      if [[ "$rsys_old" == "$rsys" ]]; then 
        echo "$rday_old $rsys_old $rser" >> output 
      else 
        echo "$rday $rsys $rser" >> output  
      fi 
      rday_old=$rday 
      rsys_old=$rsys 
      rser_old=$rser 
    done 5< input_file 

Проблема IST, очевидно, что это не будет работать, как задумано. Я не знаю, как лучше всего это решить. Мой attemp не учитывает, что день должен быть разделен, если он находится в формате 2,3 или даже 2,4,5 до 7 дней в формате crontab (который будет знаком *). Кроме того, может случиться так, что мне нужно хранить более одного rday_old, rsys_old и rser_old.

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

Edit:

После ответа @anishsane я устремил свой ответ на

cat input | awk '{sys=$2; ser=$3; split($1,a,","); for(i in a){print a[i]" " sys " " ser}}' > output 

, но она выводит теперь, как результат:

0 Sys1 server1

5 SYS2 server2

2 sys3

3 sys3 server3

0 sys3 server3

7 sys4 сервера4

....

Так я почти там.

ответ

0

gawk подход:

$ cat srvlist 
0 sys1 server1 
5 sys2 server2 
2,3 sys3 
0 sys3 server3 
7 sys4 server4 

$ awk '{sys=gensub("sys","","",$2); split($1,a,","); for(i in a){print a[i] " sys" sys " server" sys}}' srvlist 
0 sys1 server1 
5 sys2 server2 
2 sys3 server3 
3 sys3 server3 
0 sys3 server3 
7 sys4 server4 

объяснение:

  1. sys переменная извлекает номер из второго поля - SYS1, sys3 и т.д. (Это будет содержать 1, 3 соответственно)
  2. раскол первое поле запятой в качестве разделителя в массив a
  3. напечатать строку по желанию с помощью петли над a
  4. Поле 3 во входном файле игнорируется. По крайней мере, для введенного ввода, field2 & 3 всегда имеют одинаковое число.
+0

Обновлен исходный вопрос – 23rdMC

0

Вот решение Python:

#!/usr/bin/env python 

import fileinput 
import re 

for line in fileinput.input(): 
    matches = re.match('(\d),(\d) sys(\d+)', line) 
    if matches: 
     first, last, sys = matches.groups() 
     for ii in range(int(first), int(last) + 1): 
      print ii, 'sys' + sys, 'server' + sys 
    else: 
     print line, 

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

+0

Спасибо за ваш ответ. Но я предпочитаю решение bash, если это возможно. В противном случае он получает способ усложнить количество скриптов, которые мне нужно использовать. Эта проблема выше всего лишь малая часть пути больше работы – 23rdMC

0

получил его теперь решен:

[[ -e output ]] && rm output 
tac input > rev_input 
rser_old="" 
while read -u5 -r -a line; do 
     rday=${line[0]} 
     rsys=${line[1]} 
     rser=${line[2]} 
     OIFS=$IFS 
     IFS=',' 
     for x in $rday 
     do 
       [[ "$rser" == "" ]] && echo "$x $rsys $rser_old" >> output 
       [[ "$rser" != "" ]] && echo "$x $rsys $rser" >> output 
     done 
     rser_old=$rser 
     IFS=$OIFS 
done 5< rev_input 

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

Спасибо за предоставленную помощь.

Смежные вопросы