如何在变量中回显csv中的特定行和列?

时间:2016-09-20 18:03:58

标签: arrays bash csv awk sed

以下脚本:

#!/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的输出,该输出已使用多个sed命令进行解析,以将格式更改为csv。

otscurrent="$(sqlplus64 user/password@dbserverip/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" } }')"

哪个有效,但是我无法运行来自if else的命令......或者atleaste我不知道怎么做。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

  

“我试图让它只打印12 ...”

问题是IFS=","在逗号上拆分,12BBB之间没有逗号。如果您希望这些元素是单独的元素,请向IFS添加换行符。因此,替换:

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

使用:

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

输出:

$ bash test.sh
12

答案 2 :(得分:0)

您需要打印第5行第4列的值:

$ 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个命令。