Ниже приводится общее решение для транспонирования с помощью awk.
Для корректной работы нам нужно количество столбцов.
Это можно было найти при чтении файла в массив значений:
#!/bin/bash
file=i4
delimiter=""
sep=""
transpose() { : # comment sed for newer awks.
# Do this to separate characters in quite old awk
# very old wak does not allow that the FS could be Null.
#sed -e 's/./ &/g' "$file" |
awk '
{ for(i=1;i<=NF;i++){a[NR,i]=$i};{(NF>m)?m=NF:0} }
END { for(j=1; j<=m; j++)
{ for(i=1; i<=NR; i++)
{ b=((a[i,j]=="")?" ":a[i,j])
printf("%s%s",(i==1)?"":sep,b)
}
printf("\n")
}
}
' FS="$delimiter" sep="$sep" cc="$countcols" <"$file"
}
transpose
С этим файлом:
abc
fghij
klmn
opqrs
Будет напечатано:
afko
bglp
chmq
inr
j s
Awk заботится о разделении символов, если «разделитель полей» равен нулю.
Символы печатаются в одну строку, если переменная sep
также равна нулю.
Если доступный awk является более старым, нулевой FS недействителен. Используйте следующие две команды.
Чтобы подсчитать количество символов, используйте это в старых awks:
# Work with any POSIX awk to find the max character count in all rows.
countcols=$(awk '{l=length($0);(l>max)?max=l:0}END{print max}' < "$file")
Чтобы выполнить транспонирование, можно было бы добавить пробел перед каждым символом и использовать пробел в качестве «разделителя полей» и избежать пустого FS:
sed -e 's/./ &/g' < "$file" |
awk ' {for(i=1;i<=cc;i++){if($i==""){$i=" "};r[i]=r[i]sep$i;};sep=""};
END{for(i=1;i<=cc;i++)print(r[i])}
' cc="$countcols"
Прокомментируйте строку sed для более новых awks.