Home > front end >  bash: make array from table
bash: make array from table

Time:12-16

I am operating with the multiple column data: ID,num,score

7LMQ,Y6G,1.99
7LAA,Y65,2.95
7LZZ,Y55,8.106
7LDD,YAA,9.063
7N66,0HG,6.042
7444,HOP,5.02
7LJF,HEI,5.14
7LFD,LAL,4.128
7KCV,Cho,4.31
7GHJ,Ro,9.045

using some simple script I need to create two bash arrays from this data:

  1. a simple array containing elemements from the second column:

    sdf_lists=("Y6G" "Y65" "Y55" "YAA" "0HG" "HOP" "HEI" "LAL" "Cho" "Ro")

  2. an associative array made from the elements of the 2nd and the 1st columns:

    dataset=( [Y6G]=7LMQ [Y65]=7LAA [Y55]=7LZZ [YAA]=7LDD [0HG]=7N66 [HOP]=7444 [HEI]=7LJF [LAL]=7LFD [Cho]=7KCV [Ro]=7GHj ).

Do I need something complex like AWK to achive it or simple GREP solution will work as well?

CodePudding user response:

bash by itself is all you need

declare -a sdf_lists=()
declare -A dataset=()

while IFS=, read -r id sdf value; do
  sdf_lists =("$sdf")
  dataset[$id]="$sdf"
done < file.csv

declare -p sdf_lists dataset

result

declare -a sdf_lists=([0]="Y6G" [1]="Y65" [2]="Y55" [3]="YAA" [4]="0HG" [5]="HOP" [6]="HEI" [7]="LAL" [8]="Cho" [9]="Ro")
declare -A dataset=([7LMQ]="Y6G" [7LJF]="HEI" [7444]="HOP" [7GHJ]="Ro" [7KCV]="Cho" [7N66]="0HG" [7LFD]="LAL" [7LZZ]="Y55" [7LDD]="YAA" [7LAA]="Y65" )

CodePudding user response:

Data

cat col
7LMQ,Y6G,1.99
7LAA,Y65,2.95
7LZZ,Y55,8.106
7LDD,YAA,9.063
7N66,0HG,6.042
7444,HOP,5.02
7LJF,HEI,5.14
7LFD,LAL,4.128
7KCV,Cho,4.31
7GHJ,Ro,9.045

Indexed Array

bash 4

$ declare -a arr 
$ arr=($(cut -d , -f 2 col))
$ echo ${!arr[*]}
0 1 2 3 4 5 6 7 8 9
$ for i in ${!arr[*]};do echo ${arr[$i]} ;done
Y6G
Y65
Y55
YAA
0HG
HOP
HEI
LAL
Cho
Ro

zsh

$ declare -a arr                              
$ arr=($(cut -d , -f 2 col))
$ echo ${#arr}
10   
$ for i in {1..${#arr}};do echo ${arr[$i]} ;done
Y6G
Y65
Y55
YAA
0HG
HOP
HEI
LAL
Cho
Ro

Associative Array

bash 4
First loop by line and cut per entry, then associate the entries to key and value in the array.

declare -A arr

for i in $(cut -d , -f 1,2 col);do 
  arr[$(echo $i | awk -F ',' '{ print $2 }')]=$(echo $i | awk -F ',' '{ print $1 }')
done

zsh
The first approach is the same as bash 4. The second approach uses the feature of zsh that associates key/value pairs from a single line to an associative array.

declare -A arr

for i in $(cut -d , -f 1,2 col);do 
  arr[$(echo $i | awk -F ',' '{ print $2 }')]=$(echo $i | awk -F ',' '{ print $1 }')
done

# or
arr=($(awk -F ',' '{ printf " %s %s",$2,$1 } END{ print "" }' col))

Accessing

# bash 4 
for i in ${!arr[*]};do echo ${arr[$i]} ;done
7LDD
7GHJ
7LFD
7KCV
7N66
7LMQ
7LAA
7444
7LZZ
7LJF

# zsh
for i in ${(@k)arr};do echo ${arr[$i]} ;done
7LFD
7LAA
7LDD
7LZZ
7LMQ
7444
7KCV
7LJF
7GHJ
7N66
  • Related