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
उत्पादन
$ 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
एक 10000 लाइनों फ़ाइल पर जोनाथन द्वारा पर्ल समाधान के खिलाफ प्रदर्शन
$ 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 (@ ghostdog74 हटाने के लिए स्वतंत्र महसूस यदि आप अस्वीकृत)।
शायद कुछ अधिक स्पष्ट चर नामों वाला यह संस्करण नीचे दिए गए कुछ सवालों के जवाब देने में मदद करेगा और आम तौर पर यह स्पष्ट करेगा कि स्क्रिप्ट क्या कर रही है। यह विभाजक के रूप में भी टैब का उपयोग करता है जिसे ओपी ने मूल रूप से कहा था इसलिए यह खाली क्षेत्रों को संभालता है और यह संयोग से इस विशेष मामले के लिए आउटपुट को थोड़ा बढ़ा देता है।
$ 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
उपरोक्त समाधान किसी भी awk में काम करेंगे (पुराने, टूटे हुए awk के अलावा - वहाँ YMMV)।
उपरोक्त समाधान पूरी फ़ाइल को स्मृति में पढ़ते हैं - यदि इनपुट फ़ाइल उसके लिए बहुत बड़ी हैं तो आप ऐसा कर सकते हैं:
$ 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
जो लगभग किसी भी मेमोरी का उपयोग नहीं करता है, लेकिन एक लाइन पर प्रति फ़ील्ड के इनपुट फ़ाइल को एक बार पढ़ता है, इसलिए यह उस संस्करण की तुलना में बहुत धीमा होगा जो पूरी फ़ाइल को मेमोरी में पढ़ता है। यह भी मानता है कि प्रत्येक पंक्ति पर फ़ील्ड की संख्या समान है और यह GNU awk के लिए उपयोग करता है ENDFILE
और ARGIND
लेकिन कोई भी awk ऑन FNR==1
और टेस्ट के साथ भी ऐसा कर सकता है END
।