Помощь с функцией транспонирования с использованием Bash - PullRequest
0 голосов
/ 10 июня 2019

Я хочу транспонировать заданную матрицу, представленную в скрипте оценки.Я не могу использовать AWK.Функция должна быть написана на Bash.У меня есть следующий код, где AWK отлично работает с предоставленным скриптом оценки.скрипт не AWK возвращает ошибки, которые не являются обязательными или имеют неправильные размеры.в целом результаты выглядят одинаково, и я застрял на том, почему они кажутся отличными от сценария оценки.если кто-то может помочь преобразовать полосу AWK в Bash без использования AWK.

Транспонирование 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 голосов
/ 10 июня 2019

Так что перепишите скрипт awk в bash.Я использовал read -a, чтобы прочитать одну строку в массив.Затем вы просто подсчитываете количество строк NR, подсчитываете количество полей NF и дублируете скрипт awk.

Поскольку вы не предоставили никаких данных для тестирования, мне нужно было создать их самостоятельно, надеюсь, вы включите некоторые примеры ввода и пример вывода в свой следующий вопрос.

Я использовал ассоциативные массивы bash дляпродублировать индексирование a[1,0] в bash, как в 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 .

...