Home > database >  how to get values from first index of array in shell scripting?
how to get values from first index of array in shell scripting?

Time:02-25

I have below code and I want to get daily_value and priormonth value from log file. As per the code the daily_value and priormonth value are stored in first index of array.

How to search for "daily_value" and "priormonth" and get their corresponding values, so that the daily_value will be "3" and priormonth value will be "8".

sql file as shown below:

first input file columns order:

cash , monthy_value, null,null, 0.000
cash,daily_value,2022-02-22,2022-02-22,3
cash,priormonth_value,2022-02-22,2022-02,8

second input file columns order:

cash,priormonth_value,2022-02-22,2022-02,8
cash , monthy_value, null,null, 0.000
cash,daily_value,2022-02-22,2022-02-22,3

third input file columns order and in the below input file there is no "priormonth" so need to assign 'zero' value to it.

cash , monthy_value, null,null, 0.000
cash,daily_value,2022-02-22,2022-02-22,3
declare -A arr


if [ -s $sqlfile ]
then 
  while IFS=, read key value; do
          arr[$key] = "${arr[$key]}$arr[$key]: ,}$value"
  done < $sqlfile

       i=0
       for key in "${!arr[@]}"; do
       row=`echo $key | xargs`
       values = ${arr[$key]}

       daily_value = `echo $values | cut -d ',' -f8 | xargs`
       priomonth_value = `echo $value | cut -d ',' -f12 | xargs`

       i = $((i 1))
       done
else
       echo "$sqlfile is empty"
fi

exit 0

CodePudding user response:

You could use and read the output into an array:

readarray -t values <<< $(sed -nE \
    's/^[^,]*,(daily_value|priormonth_value),.*,([[:digit:]] )$/\1 \2/p' \
    < "$sqlfile" | sort | sed -E 's/^[^ ]  //')

daily_value=${values[0]}
priomonth_value=${values[1]}
  • -E - Extended regex

  • -n - Don't print lines automatically

  • /p - Print matching lines

  • ^[^,]*, - match a line starting with any number of characters (except ,) followed by a ,

  • (daily_value|priormonth_value), - match on daily_value or priormonth_value (and capture it) followed by a ,

  • .*,([[:digit:]] )$ - match any number of characters follow by a , and then 1 or more digits followed by the end of line. Capture the digits.

  • /\1 \2/ - replace the whole line with the captured digits tagged by daily_value or priormonth_value.

The second expression does the same but matches on priormonth_value instead.

Finally sort (so that daily_value comes before priormonth_value) and remove the daily_value and priormonth_value tags with sed -E 's/^[^ ] //'.

If every line always starts with cash, you can make it a little simpler by sorting first:

readarray -t values <<< $(sort "$sqlfile" | sed -nE \
    's/^cash,(daily_value|priormonth_value),.*,([[:digit:]] )$/\2/p')

CodePudding user response:

Given:

$ head file{1..3}
==> file1 <==
cash , monthy_value, null,null, 0.000
cash,daily_value,2022-02-22,2022-02-22,3
cash,priormonth_value,20shelll22-02-22,2022-02,8

==> file2 <==
cash,priormonth_value,2022-02-22,2022-02,8
cash , monthy_value, null,null, 0.000
cash,daily_value,2022-02-22,2022-02-22,3

==> file3 <==
cash , monthy_value, null,null, 0.000
cash,daily_value,2022-02-22,2022-02-22,3

I personally would use a combination of awk and Bash like so:

for fn in file{1..3}; do 
    declare -A arr
    
    while read k v; do 
        arr["$k"]="$v"
    done <<< $(awk -F, -v keys='daily_value priormonth_value' '
    BEGIN{split(keys,tmp,"[ \t] "); for (e in tmp) tgt[tmp[e]]}
    $2 in tgt {
        gsub(/\s*,\s*/,",")
        printf("%s %s\n",$2,$(NF))
    }' "$fn")
    echo "$fn"
    declare -p arr
    unset arr 
    echo 
done 

Prints:

file1
declare -A arr=([daily_value]="3" [priormonth_value]="8" )

file2
declare -A arr=([daily_value]="3" [priormonth_value]="8" )

file3
declare -A arr=([daily_value]="3" )
  • Related