gpt4 book ai didi

bash - 从文件 BASH 中对列进行排序

转载 作者:行者123 更新时间:2023-11-29 09:31:49 27 4
gpt4 key购买 nike

我有以下 shell 脚本,它从命令行输入的文件中读取数据。该文件是一个数字矩阵,我需要按列分隔文件,然后对列进行排序。现在我可以读取文件并输出各个列,但我不知道如何排序。我输入了排序语句,但它只对第一列进行排序。

编辑:我决定采取另一条路线并实际转置矩阵以将列变成行。因为我必须稍后计算平均值和中值,并且已经在脚本的前面对文件的行成功地完成了这项工作——如果你想把列变成行,有人建议我尝试“旋转”矩阵。

这是我的更新代码

     declare -a col=( )
read -a line < "$1"
numCols=${#line[@]} # save number of columns

index=0
while read -a line ; do
for (( colCount=0; colCount<${#line[@]}; colCount++ )); do
col[$index]=${line[$colCount]}
((index++))
done
done < "$1"

for (( width = 0; width < numCols; width++ )); do
for (( colCount = width; colCount < ${#col[@]}; colCount += numCols ) ); do

printf "%s\t" ${col[$colCount]}
done
printf "\n"
done

这给了我以下输出:

    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

虽然我现在正在寻找:

    1 3 3 6 6 9
1 3 4 4 6 7
1 2 4 4 8 8
1 1 5 7 9 9
1 1 4 5 7 7

为了尝试对数据进行排序,我尝试了以下方法:

    sortCol=${col[$colCount]}
eval col[$colCount]='($(sort <<<"${'$sortCol'[*]}"))'

另外:(这是我从行中读入后对行进行排序的方式)

    sortCol=( $(printf '%s\t' "${col[$colCount]}" | sort -n) )

如果您能对此提供任何见解,我们将不胜感激!

最佳答案

请注意,如评论中所述,纯 bash 解决方案并不漂亮。有很多方法可以做到这一点,但这可能是最直接的。以下要求将每行的所有值读入数组,并保存矩阵 stride 以便可以将其转置以将所有列值读入行矩阵并进行排序。所有排好序的列都被插入到新的行矩阵 a2 中。转置该行矩阵会按列排序顺序生成原始矩阵。

注意这适用于您文件中任何列矩阵的等级。

#!/bin/bash

test -z "$1" && { ## validate number of input
printf "insufficient input. usage: %s <filename>\n" "${0//*\//}"
exit 1;
}

test -r "$1" || { ## validate file was readable
printf "error: file not readable '%s'. usage: %s <filename>\n" "$1" "${0//*\//}"
exit 1;
}

## function: my sort integer array - accepts array and returns sorted array
## Usage: array=( "$(msia ${array[@]})" )
msia() {
local a=( "$@" )
local sz=${#a[@]}
local _tmp
[[ $sz -lt 2 ]] && { echo "Warning: array not passed to fxn 'msia'"; return 1; }
for((i=0;i<$sz;i++)); do
for((j=$((sz-1));j>i;j--)); do
[[ ${a[$i]} -gt ${a[$j]} ]] && {
_tmp=${a[$i]}
a[$i]=${a[$j]}
a[$j]=$_tmp
}
done
done
echo ${a[@]}
unset _tmp
unset sz
return 0
}

declare -a a1 ## declare arrays and matrix variables
declare -a a2
declare -i cnt=0
declare -i stride=0
declare -i sz=0

while read line; do ## read all lines into array
a1+=( $line );
(( cnt == 0 )) && stride=${#a1[@]} ## calculate matrix stride
(( cnt++ ))
done < "$1"

sz=${#a1[@]} ## calculate matrix size
## print original array
printf "\noriginal array:\n\n"
for ((i = 0; i < sz; i += stride)); do
for ((j = 0; j < stride; j++)); do
printf " %s" ${a1[i+j]}
done
printf "\n"
done

## sort columns from stride array
for ((j = 0; j < stride; j++)); do
for ((i = 0; i < sz; i += stride)); do
arow+=( ${a1[i+j]} )
done
a2+=( $(msia ${arow[@]}) ) ## create sorted array
unset arow
done
## print the sorted array
printf "\nsorted array:\n\n"
for ((j = 0; j < cnt; j++)); do
for ((i = 0; i < sz; i += cnt)); do
printf " %s" ${a2[i+j]}
done
printf "\n"
done

exit 0

输出

$ bash sort_cols2.sh dat/matrix.txt

original array:

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

sorted array:

1 1 1 1 1
3 3 2 1 1
3 4 4 5 4
6 4 4 7 5
6 6 8 9 7
9 7 8 9 7

关于bash - 从文件 BASH 中对列进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29789649/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com