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_valueorpriormonth_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_valueorpriormonth_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" )
