2015-01-07 42 views
0

我有一個文本文件我通過從各種服務器的crontabs bash腳本,看起來像這樣格式生成:如何在bash中將輸入文件格式化爲特殊格式?

0 SYS1 server1的

5 SYS2 server2的

2,3- SYS3

0 sys3 server3

7 sys4 server4

....

,我希望它得到格式化這樣的:

0 SYS1 server1的

5系統2服務器2

2 SYS3 server(服務器)

3 SYS3 server3

0 sys3 server3

7 SYS4服務器4

....

的問題我已經是我也可以隨時更改如果每個SYS /服務器以上兩個數字,有可能是還不止每個服務器有兩個crontab條目。

我學嘗試是這樣的:

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顯然,它不會像預期那樣發揮作用。我不知道解決這個問題的最好方法是什麼。我的嘗試沒有考慮到需要拆分的日子,如果它的格式爲2,3或2,4,5到7天(以crontab格式)(這將是*符號)。此外,它可能會發生,我需要存儲多個rday_old,rsys_old和rser_old。

我希望我以一種可以理解的方式表達我的問題。 感謝您提前提供任何幫助。

編輯:

@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系統2 server2

2 SYS3

3 SYS3服務器3

0 SYS3服務器3

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。至少對於提供的輸入,字段2 & 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腳本,這並不在所有問題。

感謝您提供的幫助。

相關問題