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 sed 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 ondaily_value
orpriormonth_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 bydaily_value
orpriormonth_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" )