我有一个小问题,我有一个看起来像这样的数组,我从输入文件读取它(cols由制表符分隔):
1 1 1 1 1
9 3 4 5 5
6 7 8 9 7
3 6 8 9 1
3 4 2 1 4
6 4 4 7 7
a=[1 1 1 1 1 9 3 4 5 5 6 7 8 9 7 3 6 8 9 1 3 4 2 1 4 6 4 4 7 7]
现在我正在尝试编写一个代码,它应该以这种方式提供输出(组合每个第6个元素并形成一个数组并打印出来:
1 9 6 3 3 6
1 3 7 6 4 4
1 4 8 8 2 4
1 5 9 9 1 7
1 5 7 1 4 7
我是bash的新手并尝试编写此代码(iter = no of cols-1):
for ((i=0; i< $iter;i++))
do
for ((j=i; j< ${#a[@]}; j+$cols))
do
echo "${a[j]}"
done
done
我已编写此代码,但它将进入无限循环。怎么解决这个问题。有没有更简单的方法呢?这是我的整个脚本:
#! /bin/bash
clear
declare -i rem= 1
if [ "$#" -eq 0 ]; then
echo "Please provide arguments"
elif [ "$#" -lt 2 ]; then
echo "You have to provide 2 arguments"
elif [ "$#" -gt 2 ]; then
echo "You have provided more number of arguments"
else
echo "You have entered correct number of arguments"
fi
option="${1}"
case ${option} in
-rows| -r) FILE="${2}"
echo "rows"
echo "File name is $FILE"
clear
echo "Average Median"
while read -r line
do
len=0
tot=0
name=$line
IFS=" " read -a array <<< "$name"
for element in "${array[@]}"
do
tot=$(expr $tot + $element)
#let tot+=$element #you can use this as well to get the totals
let len+=1
done
avg= printf "%.0f" $(echo "scale=2;$tot/$len" | bc)
readarray -t sorted < <(for a in "${array[@]}"; do echo "$a"; done | sort)
no=`expr $len % 2`
if [ $no -eq 0 ]; then
mid=`expr $len / 2`
echo "$avg ${sorted[$mid]}"
else
mid=`expr $len / 2`
echo "$avg ${sorted[$mid]}"
fi
unset "array[@]"
unset "sorted[@]"
done < "$FILE"
;;
-cols| -c) FILE="${2}"
echo "cols"
echo "File name is $FILE"
cols=$(head -1 "$FILE" | tr "\t" '\n' | wc -l)
lines=$(wc -l < "$FILE")
iter=`expr $cols - $rem`
echo $iter
echo $cols
echo $lines
readarray a < "$FILE"
echo ${a[@]}
while read line;do
x=1
read -a array <<< "$line" ##Split the line by spaces
for element in "${!array[@]}"
do
row[${element}]=$((${row[${element}]}+${array[$element]})) ##For each column increment array variable by number in the column.
((x++))
done
done < "$FILE"
for element in ${row[@]}
do
mean= printf "%.0f" $(echo "scale=2;$element/$x" | bc) ##bc prints floating point numbers and then we round of using scale and .0f
echo -n "$mean "
done
printf "\n"
;;
*)
echo "`basename ${0}`:usage: [-r|-rows rows] | [-c|-cols columns]"
exit 1 # Command to come out of the program with status 1
;;
esac
可以这样运行:
./stats.sh -rows test_file or ./stat.sh -cols test_file
答案 0 :(得分:1)
#!/usr/bin/env bash
rows=6 # number of rows of the original matrix
cols=5 # number of columns of the original matrix
a=(1 1 1 1 1 9 3 4 5 5 6 7 8 9 7 3 6 8 9 1 3 4 2 1 4 6 4 4 7 7) # bash array is wrapped in parentheses
for ((i = 0; i < cols; i++)); do # i is the row index of the transposed matrix
for ((j = 0; j < rows; j++)); do # j is the column index of the transposed matrix
linear_index=$((j * cols + i)) # index in the array
((j != 0)) && printf "\t" # print a tab if not the first element of the row
printf "${a[${linear_index}]}" # print the element
done
printf "\n" # print a newline at the end of each row
done
或者使用我不喜欢的原始流量控制因为索引的对称性被破坏了:
#!/usr/bin/env bash
a=(1 1 1 1 1 9 3 4 5 5 6 7 8 9 7 3 6 8 9 1 3 4 2 1 4 6 4 4 7 7)
len=${#a[@]}
cols=5
for ((i = 0; i < cols; i++)); do
printf ${a[i]} # treat the first element specially since I hate trailing whitespace
for ((j = i + col; j < len; j += cols)); do
printf "\t${a[j]}"
done
printf "\n"
done
答案 1 :(得分:1)
定义列表a
:
$ a="1 1 1 1 1 9 3 4 5 5 6 7 8 9 7 3 6 8 9 1 3 4 2 1 4 6 4 4 7 7"
打印矩阵:
$ awk '{for (i=1;i<=5;i++){for (j=i;j<=NF;j=j+5)printf "%s ",$j; print""}}' <<<"$a"
1 9 6 3 3 6
1 3 7 6 4 4
1 4 8 8 2 4
1 5 9 9 1 7
1 5 7 1 4 7
$ a=(1 1 1 1 1 9 3 4 5 5 6 7 8 9 7 3 6 8 9 1 3 4 2 1 4 6 4 4 7 7)
$ for ((i=0;i<5;i++)) do for ((j=i;j<30;j=j+5)) do printf "%s " ${a[$j]}; done; echo "";done <<<"$a"
1 9 6 3 3 6
1 3 7 6 4 4
1 4 8 8 2 4
1 5 9 9 1 7
1 5 7 1 4 7
如果要将其放入脚本中,而不是在命令行上执行,可能需要将其拆分为多行:
a=(1 1 1 1 1 9 3 4 5 5 6 7 8 9 7 3 6 8 9 1 3 4 2 1 4 6 4 4 7 7)
for ((i=0;i<5;i++))
do
for ((j=i;j<30;j=j+5))
do
printf "%s " ${a[$j]}
done
echo ""
done <<<"$a"