使用Bash协助移调功能

时间:2019-06-09 22:50:41

标签: bash awk transpose

我想转置分级脚本中提供的给定矩阵。我不能使用AWK。该函数必须用Bash编写。我有以下代码,其中AWK与提供的评分脚本完美配合。非AWK脚本会返回错误,指出该错误不是强制性的或尺寸不正确。所有的输出看起来都很相似,我被困在为什么它们看起来与分级脚本不同的地方。如果有人可以在不利用AWK的情况下帮助他人将AWK转换为Bash。

转置1-一种读取文件的方式

DONE=false
until $DONE;
do
    read -a myLine || DONE=true
    for ((i=0;i<"${#myLine[@]}";i++))
    do
        temp_array[$i]+=" ${myLine[$i]}"
    done
done < $1

for ((i=0;i<${#temp_array[@]};i++))
do
    printf "%s\t" ${temp_array[i]} >> temp_file
    printf "\n" >> temp_file
done

转置2-读取文件。会将所有行读入数组。

while read -a myLine || [[ ${#myLine[@]} -gt 0 ]]
do
    for ((i=0;i<"${#myLine[@]}";i++))
    do
        temp_array[$i]+=" ${myLine[$i]}"
    done
done < $1

for ((i=0;i<${#temp_array[@]};i++))
do
    printf "%s\t" ${temp_array[i]} >> temp_file
    printf "\n" >> temp_file
done

cat temp_file
rm temp_file

两者都能工作,并且看起来具有相同的输出。

此代码与分级脚本完美配合:

cp $1 $temp_input    #copy file to temp file named temp_input
awk '{ for (i=1; i<=NF; i++) {a[NR,i] = $i} }
NF>p { p = NF }
END { 
    for(j=1; j<=p; j++) {
        str=a[1,j]
        for(i=2; i<=NR; i++)
    {str=str"    "a[i,j];}
    printf str"\n"}
}' $temp_input # for loop to transpose temp_input file contents
rm $temp_input

预期结果是一个并非不可取的转置矩阵。 NON-AWK代码的结果和使用AWK提供的代码的结果都应具有相同的准确输出。请帮忙。

1 个答案:

答案 0 :(得分:0)

因此将awk脚本重写为bash。我使用read -a将一行读入数组。然后,您只需计算行数NR和计算字段数NF并复制awk脚本即可。

由于您没有提供任何数据进行测试,因此我需要自己创建一些数据,希望您在下一个问题中包括一些示例输入和示例输出。

我使用关联的bash数组来复制bash中的a[1,0]索引,就像在awk中一样。

cat << EOF > file
1  2  3  4
5  6  7  8
9 10 11 12
EOF

echo -------------- awk
< file awk '{ for (i=1; i<=NF; i++) {a[NR,i] = $i} }
NF>p { p = NF }
END { 
    for(j=1; j<=p; j++) {
        str=a[1,j]
        for(i=2; i<=NR; i++)
    {str=str"    "a[i,j];}
    printf str"\n"}
}'

echo ------------ bash

# same in bash
# note indexes start with 0
declare -A a
NR=0
while IFS=$' \t' read -r -a line; do
  for i in ${!line[@]}; do
    a[$NR,$i]="${line[$i]}"
  done
  ((NR++)) ||:
done < file
NF=$i
for ((j = 0; j <= NF; j++)); do
  str="${a[0,$j]}"
  for ((i = 1; i < NR; i++)); do
    str+="    ${a[$i,$j]}"
  done
  printf "%s\n" "$str"
done

将输出:

-------------- awk
1    5    9
2    6    10
3    7    11
4    8    12
------------ bash
1    5    9
2    6    10
3    7    11
4    8    12

经过测试并用repl.it编写。