Bash
使用 shell 腳本操作文本:如何填寫“缺失”行?
我有一個數據列表,例如 CSV,但有些行缺少值。我想根據使用 linux shell 腳本之前和之後的行為缺少的行生成一個值。
以這張桌子為例。
我想做的是用“Cindy:Ed”(B列中每個方向上最近的有效數據與“:”分隔符的連接)和“#”填寫第4行的“*” 48(47 和 49 的平均值,C 列每個方向上最近的有效數據點)。
輸出:
我的數據被格式化為任意行數的空格分隔文本文件。所有行都是三列。
雖然我知道 For 循環和 grep 等的方法,但我不知道如何在 vanilla linux shell 腳本中處理這個問題。
我的猜測是進行初始傳遞以查找具有星號和雜湊的行。然後進行第二遍,分別用 (awk ‘{print $2}’):(awk ‘{print $2}’) 之前和之後的行替換星號。
如果失去的數據在第一行或最後一行,我很樂意保持原樣。如果失去的數據在連續的行上,我可以將所有失去的行設置為相同的“Cindy:Ed”和相同的平均值。如果我能設置 “Cindy:Ed:1” 和 Cindy:Ed:2" 等就更酷了。
最壞情況原始輸入的準確範例:(它是一個跟踪路由,添加了“#”表示缺少的延遲)
1 192.168.200.2 1 2 192.168.200.1 1 3 10.10.10.1 1 4 11.22.33.44 2 5 11.22.33.55 5 6 * # 7 11.22.44.66 9 8 * # 9 * # 10 8.8.8.0 25 11 * # 12 * # 13 * #
我想要什麼:
1 192.168.200.2 1 2 192.168.200.1 1 3 10.10.10.1 1 4 11.22.33.44 2 5 11.22.33.55 5 6 11.22.33.55:11.22.44.66 7 7 11.22.44.66 9 8 11.22.44.66:8.8.8.0 17 9 11.22.44.66:8.8.8.0 17 10 8.8.8.0 25 11 * # 12 * # 13 * #
與
awk
:#if a previous line with proper IP has been read oldip != "" { #i is counter for consecutive invalid lines i=0 #if IP is set, just print and go to next record if ($2!="*") { print ; oldip=$2 ; oldlat=$3 ; next } #otherwise get following line and increase counter else { #getline exit status => fails for the last line while (getline > 0) {i++ #check if new line has IP, if so #set IPold:IPnew and average latency value if ($2!="*") { ipfill=oldip":"$2 ; latfill=(oldlat+$3)/2 #print filler lines for all consecutive records without value for (j=1 ; j<=i ; j++) { print NR-i+j-1,ipfill,latfill #alternative printing with oldIP:newIP:counter # print NR-i+j-1,ipfill":"j,latfill } #save current IP+lat and print "good" line oldp=$2; oldlat=$3 print ; next } } } #in case getline failed => all previous lines had no value #just fill them with N/A data as in input for (j=0 ; j<=i ; j++) { print NR-i+j,"*","#" } } #If leading lines have no IP value, print them until IP is found oldip == "" { if ($2=="*") {print ; next} ; oldip=$2 ; oldlat=$3 ; print }
輸入:
1 * # 2 * # 3 10.10.10.1 1 4 11.22.33.44 2 5 11.22.33.55 5 6 * # 7 11.22.44.66 10 8 * # 9 * # 10 8.8.8.0 25 11 * # 12 * # 13 * #
輸出:
1 * # 2 * # 3 10.10.10.1 1 4 11.22.33.44 2 5 11.22.33.55 5 6 11.22.33.55:11.22.44.66 7.5 7 11.22.44.66 10 8 11.22.33.55:8.8.8.0 17.5 9 11.22.33.55:8.8.8.0 17.5 10 8.8.8.0 25 11 * # 12 * # 13 * #
計算行的帶有計數器的替代輸出:
1 * # 2 * # 3 10.10.10.1 1 4 11.22.33.44 2 5 11.22.33.55 5 6 11.22.33.55:11.22.44.66:1 7.5 7 11.22.44.66 10 8 11.22.33.55:8.8.8.0:1 17.5 9 11.22.33.55:8.8.8.0:2 17.5 10 8.8.8.0 25 11 * # 12 * # 13 * #