2016-09-20 64 views
0

下面的腳本:我如何在變量中聲明csv的特定行和列?

#!/bin/bash 
otscurrent=" 
AAA,33854,4528,38382,12 
BBB,83917,12296,96213,13 
CCC,20399,5396,25795,21 
DDD,27198,4884,32082,15 
EEE,2472,981,3453,28 
FFF,3207,851,4058,21 
GGG,30621,4595,35216,13 
HHH,8450,1504,9954,15 
III,4963,2157,7120,30 
JJJ,51,59,110,54 
KKK,87,123,210,59 
LLL,573,144,717,20 
MMM,617,1841,2458,75 
NNN,234,76,310,25 
OOO,12433,1908,14341,13 
PPP,10627,1428,12055,12 
QQQ,510,514,1024,50 
RRR,1361,687,2048,34 
SSS,1,24,25,96 
TTT,0,5,5,100 
UUU,294,1606,1900,85 
" 

IFS="," array1=(${otscurrent}) 

echo ${array1[4]} 

打印:

$ ./test.sh 
12 
BBB 

我試圖得到它只是打印12 ......我甚至不知道如何使它只打印一行5第4列

該變量是sqlquery的輸出,該sqlquery已使用多個sed命令解析並將格式更改爲csv。

otscurrent="$(sqlplus64 user/[email protected]/db as sysdba @query.sql | 
sed '1,11d; /^-/d; s/[[:space:]]\{1,\}/,/g; $d' | 
sed '$d'|sed '$d'|sed '$d' | sed '$d' | 
sed 's/Used,MB/Used MB/g' | 
sed 's/Free,MB/Free MB/g' | 
sed 's/Total,MB/Total MB/g' | 
sed 's/Pct.,Free/Pct. Free/g' | 
sed '1b;/^Name/d' | 
sed '/^$/d' 
)" 

最終,我希望能夠調用行和列並在值上運行語句。

起初,我認爲管道進入:

awk -F "," 'NR>1{ if($5 < 10) { printf "%-30s%-10s%-10s%-10s%-10s\n", $1,$2,$3,$4,$5"%"; } else { echo "Nothing to do" } }')" 

其中一期工程,但我無法逃避,如果其他的命令......或atleaste我不知道怎麼辦。

+1

回覆:挑選出一個特定的行和列,這是知識庫中已經存在的其他幾個問題。 –

+0

即。 HTTP://計算器。com/questions/11625533/how-can-i-print-a-specific-from-a-specific-line-in-a-delimited-type-file –

+2

awk不僅可以格式化/解析你的csv數據,它也可以像任何編程語言一樣進行條件/循環等。 – anubhava

回答

0

所有你需要打印在第五行的第四列的值是:

$ awk -F, 'NR==5{print $4}' <<< "$otscurrent" 
3453 

,並只記得在awk行(記錄)和列(字段)編號從1開始,而不是0.更多示例:

$ awk -F, 'NR==1{print $5}' <<< "$otscurrent" 
12 

$ awk -F, 'NR==2{print $1}' <<< "$otscurrent" 
BBB 

$ awk -F, '$5 > 50' <<< "$otscurrent" 
JJJ,51,59,110,54 
KKK,87,123,210,59 
MMM,617,1841,2458,75 
SSS,1,24,25,96 
TTT,0,5,5,100 
UUU,294,1606,1900,85 

如果你想避免所有的複雜性,並簡單地解析你的SQL輸出產生你想要的,而不需要20 sed命令,發佈一個新的問題,顯示原始的sqlplus輸出作爲輸入和你最終想要輸出的內容有人會發佈一個簡短,清晰,簡單,高效的awk腳本來一次完成這一切,或者如果你仍然需要一箇中間的CSV出於某種原因,也許2個命令。

1

「我試圖得到它只是打印12 ......」

問題是逗號是IFS=","分裂和有12BBB之間沒有逗號。如果你想要這些單獨的元素,添加一個換行符到IFS。因此,更換:

IFS="," array1=(${otscurrent}) 

有了:

IFS=$',\n' array1=(${otscurrent}) 

輸出:

$ bash test.sh 
12 
+1

更好的教會人們使用'IFS = $',\ n'讀取-r -d''-a array1 <

2

如果你有bash的4.0或更新版本,關聯數組是將數據存儲在這種適當的方式的形式。

otscurrent=${otscurrent#$'\n'} # strip leading newline present in your sample data 

declare -A data=() 

row=0 
while IFS=, read -r -a line; do 
    for idx in "${!line[@]}"; do 
    data["$row,$idx"]=${line[$idx]} 
    done 
    ((row += 1)) 
done <<<"$otscurrent" 

這使您可以訪問各個項目:

echo "${data[0,0]}" # first field of first line 
echo "${data[9,0]}" # first field of tenth line 
echo "${data[9,1]}" # second field of tenth line 
+0

'read'避免了路徑名擴展:+1。 – John1024

+0

這是一個魅力......現在理解這裏的邏輯..這是一個很好的起點......我很感激任何我可以參考的解釋。 – substancev

+0

那麼如果我想說如果第五個字段大於10的行應該回顯到屏幕上呢? – substancev