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];
}
print str
}
}' file
çıktı
$ more file
0 1 2
3 4 5
6 7 8
9 10 11
$ ./shell.sh
0 3 6 9
1 4 7 10
2 5 8 11
Jonathan tarafından 10000 satırlık bir dosyada Perl çözümüne karşı performans
$ head -5 file
1 0 1 2
2 3 4 5
3 6 7 8
4 9 10 11
1 0 1 2
$ wc -l < file
10000
$ time perl test.pl file >/dev/null
real 0m0.480s
user 0m0.442s
sys 0m0.026s
$ time awk -f test.awk file >/dev/null
real 0m0.382s
user 0m0.367s
sys 0m0.011s
$ time perl test.pl file >/dev/null
real 0m0.481s
user 0m0.431s
sys 0m0.022s
$ time awk -f test.awk file >/dev/null
real 0m0.390s
user 0m0.370s
sys 0m0.010s
EDIT by Ed Morton (@ ghostdog74, onaylamazsanız silmekten çekinmeyin).
Belki daha açık değişken adlarına sahip bu sürüm, aşağıdaki soruların bazılarının yanıtlanmasına yardımcı olur ve genel olarak betiğin ne yaptığını netleştirir. Ayrıca, OP'nin başlangıçta istediği ayırıcı olarak sekmeleri kullanır, böylece boş alanları ele alır ve tesadüfen, bu özel durum için çıktıyı biraz güzelleştirir.
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
for (rowNr=1;rowNr<=NF;rowNr++) {
cell[rowNr,NR] = $rowNr
}
maxRows = (NF > maxRows ? NF : maxRows)
maxCols = NR
}
END {
for (rowNr=1;rowNr<=maxRows;rowNr++) {
for (colNr=1;colNr<=maxCols;colNr++) {
printf "%s%s", cell[rowNr,colNr], (colNr < maxCols ? OFS : ORS)
}
}
}
$ awk -f tst.awk file
X row1 row2 row3 row4
column1 0 3 6 9
column2 1 4 7 10
column3 2 5 8 11
Yukarıdaki çözümler herhangi bir awk'de çalışacaktır (tabii ki eski, bozuk awk hariç - orada YMMV).
Yukarıdaki çözümler tüm dosyayı belleğe okur - eğer giriş dosyaları bunun için çok büyükse, o zaman bunu yapabilirsiniz:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{ printf "%s%s", (FNR>1 ? OFS : ""), $ARGIND }
ENDFILE {
print ""
if (ARGIND < NF) {
ARGV[ARGC] = FILENAME
ARGC++
}
}
$ awk -f tst.awk file
X row1 row2 row3 row4
column1 0 3 6 9
column2 1 4 7 10
column3 2 5 8 11
Neredeyse hiç bellek kullanmayan, ancak girdi dosyasını bir satırdaki alan sayısı başına bir kez okur, böylece tüm dosyayı belleğe okuyan sürümden çok daha yavaş olacaktır. Ayrıca alan sayısının her satırda aynı olduğunu varsayar ve için GNU awk kullanır ENDFILE
ve ARGIND
ancak herhangi bir awk, FNR==1
ve üzerindeki testlerle aynı şeyi yapabilir END
.