সীমাহীন সংখ্যক কলাম অদলবদল করা


12

আমার কাছে কলাম সহ একটি ফাইল আছে। একটি উদাহরণ জন্য নিচে দেখুন:

a b c ... z  
1 2 3 ... 26

আমি সমস্ত কলামগুলি অদলবদল করতে চাই যেখানে ১ ম সর্বশেষ হয়, দ্বিতীয়টি শেষের আগে হয়ে যায় ... ইত্যাদি ..

z y x ... a  
26 25 24 ... 1

এমন কোনও লাইন আছে ( awkবা sed) যা এটি করে?
আমি জানি awkযখন কেবল কয়েকটি দম্পতি কলাম থাকবে তখন একটি ব্যবহার করতে পারে তবে আমি হাজার হাজার কলাম সহ ফাইলগুলিতে এটি করতে সক্ষম হতে চাই।

tacলাইন জন্য এই নিখুঁতভাবে না।
আমার ধারণা আমি কলামগুলির সমতুল্য খুঁজছি।

rev এটি আমার পক্ষে কাজ করেনি, কারণ এটি কলামে সামগ্রীকেও অদলবদল করে।


perl -lane 'print join " ", reverse @F'

উত্তর:


15
awk '{for(i=NF;i>0;i--)printf "%s ",$i;print ""}' file

আমি এত সাধারণ কাজের জন্য খুব পরিশ্রম করেছি। সর্বদা সহজ এটি আরও ভাল। +1
বিরিরে

10

আপনি এটি একটি অজগর স্ক্রিপ্ট দিয়ে করতে পারেন:

#!/usr/bin/env python

# Swaps order of columns in file, writes result to a file.
# usage: program.py input_file output_file

import sys, os

out = []

for line in open(sys.argv[1], 'r'):
    fields = line.split()
    rev = ' '.join(list(reversed(fields)))
    out.append(rev)

f = open(sys.argv[2], 'w')
f.write(os.linesep.join(out))

7

যদি আপনি অজগরকে কিছু মনে করেন না তবে এই ওয়ান-লাইনারটি প্রতিটি লাইনে স্থান পৃথক কলামগুলির ক্রমটিকে বিপরীত করবে:

paddy$ cat infile.txt 
a b c d e f g h i j k l
1 2 3 4 5 6 7 8 9 10 11 12
a e i o u
paddy$ python3 -c 'with open("infile.txt") as f: print("\n".join(" ".join(line.rstrip().split()[::-1]) for line in f))'
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a
paddy$ 

উপরোক্ত পাইথন 2.7 নিয়েও কাজ করে:

paddy$ python2.7 -c 'with open("infile.txt") as f: print("\n".join(" ".join(line.rstrip().split()[::-1]) for line in f))'
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a
paddy$ 

এই পদ্ধতিটি আমি পরীক্ষিত সমস্ত আনসারদের থেকে দ্রুততম।
পিটার.ও

4

এক উপায় ব্যবহার awk

এর বিষয়বস্তু infile:

a b c d e f g h i j k l
1 2 3 4 5 6 7 8 9 10 11 12
a e i o u

নিম্নলিখিত awkকমান্ড চালান :

awk '{
    ## Variable 'i' will be incremented from first field, variable 'j'
    ## will be decremented from last field. And their values will be exchanged.
    ## The loop will end when both values cross themselves.
    j = NF; 
    for ( i = 1; i <= NF; i++ ) { 
        if ( j - i < 1 ) { 
            break;
        } 
        temp = $j; 
        $j = $i; 
        $i = temp; 
        j--; 
    }
    print;
}' infile

নিম্নলিখিত ফলাফল সহ:

l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a

3

এটি ধীর গতিযুক্ত তবে এটির একটি মুক্তির বৈশিষ্ট্য রয়েছে। এটি ক্ষেত্র বিভাজকগুলির প্রস্থকে বজায় রাখে, যখন তারা একক অক্ষরের চেয়ে প্রশস্ত থাকে। এফডব্লিউআইডাব্লু: আপনি যদি এই স্ক্রিপ্টটি দু'বার চালনা করেন তবে ফলাফলটি আসলটির মতো।

এখানে স্ক্রিপ্ট।

awk '{ eix = length($0) 
       for( fn=NF; fn>0; fn--) { dix=eix
            while( substr($0,dix,1) ~ /[ \t]/ ) dix--
            printf "%s%s", substr($0,dix+1,eix-dix), $fn
            dix-=length($fn); eix=dix }
       print substr($0,1,dix)
    }' "$file"

এখানে কিছু সময়ের তুলনা করা হচ্ছে। পরীক্ষার ফাইলটিতে 1 লাইন রয়েছে।

                      fields           fields     
                      10,0000          10,000,000

user11136 {python} | real  0.029s     real  3.235s
reversible? no     | user  0.032s     user  2.008s
                   | sys   0.000s     sys   1.228s

jmp {python}       | real  0.078s     real  5.045s
reversible? no     | user  0.068s     user  4.268s
                   | sys   0.012s     sys   0.560s

rush {awk}         | real  0.120s     real  10.889s
reversible? no     | user  0.116s     user   8.641s
                   | sys   0.008s     sys    2.252s

petero {awk}       | real  0.319s     real  35.750s
reversible? yes    | user  0.304s     user  33.090s
                   | sys   0.016s     sys    2.660s

3

আপনি কেবল ইনপুটটি আগে এবং পরে স্থানান্তর করতে পারেন tacতা ব্যবহার করতে পারেন । এটি স্প্রেডশিট ক্যালকুলেটর scএবং এর সাইডকিক দিয়ে করা যেতে পারে psc:

< infile psc -S -r | sc -W% - | tac | psc -S -r | sc -W% - > outfile

যেমনটি এখানে দেখা যায় ।

সমস্ত কলামগুলি পূর্ণ হয়ে গেলে এটি সর্বোত্তম কাজ করে।

এর infile

 a b c d e f g h i  j  k  l
 1 2 3 4 5 6 7 8 9 10 11 12
 A B C D E F G H I  J  K  L

outfile

  l  k  j i h g f e d c b a
 12 11 10 9 8 7 6 5 4 3 2 1
  L  K  J I H G F E D C B A

সম্পাদন করা

পিটারও দ্বারা উল্লিখিত হিসাবে sc702 কলামগুলির একটি হার্ড সীমা রয়েছে, সুতরাং এটি এই পদ্ধতির দ্বারা সমর্থিত সর্বাধিক আকার।


1
এটি সংখ্যাগুলিকে ভাসমান পয়েন্টগুলিতে রূপান্তর করে (আমার জন্য) যেমন। 1-> 1.00। এছাড়াও, আমি 702 টিরও বেশি ক্ষেত্রের প্রশস্ত লাইনের জন্য ত্রুটি পেয়েছি। এটি 32768 এর সংখ্যার সীমাতে সম্পর্কিত বলে মনে হচ্ছে ... তবে এটি বেশ দ্রুত, এসিস।
পিটার.ও

আমি ভাসমান পয়েন্ট রূপান্তরটি দেখতে পাচ্ছি না, তবে কমান্ডে যুক্ত -Sকরার সাথে সমস্ত pscকিছুকে স্ট্রিং হিসাবে ব্যাখ্যা করা উচিত। 702 কলামের সীমা সম্পর্কে, এটি একটি শক্ত সীমা কারণ কেবল A থেকে ZZ কলাম সমর্থিত (26 + 26 * 26), আমি সে সম্পর্কে একটি মন্তব্য যুক্ত করব।
থোর

1
আসলে, ভাসমান পয়েন্টের সমস্যাটি ঠিক আছে I আমি এটি আরও খতিয়ে দেখলাম, এবং আমি আবিষ্কার করেছি যে দরজাটি বেরোনোর ​​সময় আমার ফলাফলগুলি পরীক্ষা করা উচিত নয় .. ভাসমান পয়েন্টগুলি কেবল 702 সীমা হিট করার পরে ঘটে ... 702 ক্ষেত্রের 1 লাইনের জন্য পাইথন উত্তরের চেয়ে দ্রুত , তবে 100 টি লাইনের জন্য এটি প্রদত্ত সমস্ত পদ্ধতির মধ্যে সবচেয়ে ধীর হয়ে যায় :( .. এটি অবশ্যই অজগর থেকে কম সংক্ষিপ্ত সময় থাকতে হবে
পিটার.ও

3

এই পাইপলাইনটি একটি উল্লেখযোগ্য ফ্যাক্টরের দ্রুততম উত্তরগুলির তুলনায় দ্রুত (ফলাফল দেখুন)। এটি ব্যবহার করে trএবং tac। এটিতে আপনার 2 এএসসিআইআই বাইট (\ x00- \ x7F) ব্যবহার করা দরকার যা আপনার ডেটাতে নেই।

\x00সাধারণত যেমন হয় তেমন ভাল পছন্দ, \x01তবে আপনি কোনও ASCII বাইট ব্যবহার করতে পারেন যা ডেটাতে নেই।

এই উদাহরণস্বরূপ, সীমাবদ্ধ করা অক্ষর হিসাবে স্পেস এবং ট্যাব। ডিলিমিটারগুলি মাল্টি-বাইট বা একক হতে পারে। আউটপুট ডিলিমিটার একটি একক স্থান।

কমান্ডটি এখানে। ফাইলের numberof fieldsনামটি _ x প্রদর্শন করেnumber of lines

 <"$file" tr ' \t\n' '\0\0\1' |tr -s '\0' '\n' |tac |tr '\n' ' ' |tr '\1' '\n'

আপনি যদি অব্যবহৃত বাইটগুলি পরীক্ষা করতে চান / চান তবে এই optionচ্ছিক awkস্ক্রিপ্টটি দিয়ে আপনি আগেই চেক করতে পারেন । সামগ্রিক সময়, এমনকি এই alচ্ছিক স্ক্রিপ্টটি চলাকালীন, এখনও অন্য মেটোডের তুলনায় এখনও দ্রুতগতিতে রয়েছে (এখনও অবধি :) .. এখানে প্রাক-প্রক্রিয়াজাতকরণ স্ক্রিপ্ট রয়েছে।

o=($(<"$file" char-ascii-not-in-stream)); x="${o[0]}"; y="${o[1]}"
<"$file" tr ' \t\n' "$x$x$y" |tr -s "$x" '\n' |tac |tr '\n' ' ' | tr '$y' '\n' >"$file".$user

এটি অ্যাজ্ক স্ক্রিপ্ট: char-ascii-not-in-stream

#!/usr/bin/awk -f
{c[$0]} END{for(i=0;i<=127;i++) {if(sprintf("%c", i) in c);else {printf "\\%03o ",i}}}

এই স্ক্রিপ্টের জন্য দ্বিতীয় সেটগুলি char-ascii-not-in-streamএর সময় অন্তর্ভুক্ত করে ।

Peter.O {tr,tac,tr} ==== file_10_x10000
real    0m0.013s    0m0.015s
user    0m0.020s    0m0.020s
sys     0m0.008s    0m0.012s   

user11136 {python} ===== file_10_x10000
real    0m0.057s
user    0m0.048s
sys     0m0.008s

jmp {python} =========== file_10_x10000
real    0m0.160s
user    0m0.160s
sys     0m0.000s

rush {awk} ============= file_10_x10000
real    0m0.121s
user    0m0.120s
sys     0m0.000s

##############################################

Peter.O {tr,tac,tr} ==== file_1000_x1000
real    0m0.048s    0m0.059s
user    0m0.040s    0m0.040s
sys     0m0.040s    0m0.048s

user11136 {python} ===== file_1000_x1000
real    0m0.158s
user    0m0.136s
sys     0m0.028s

jmp {python} =========== file_1000_x1000
real    0m0.327s
user    0m0.320s
sys     0m0.008s

rush {awk} ============= file_1000_x1000
real    0m0.832s
user    0m0.820s
sys     0m0s012s

##############################################

Peter.O {tr,tac,tr} ==== file_1000000_x50
real    0m5.221s    0m6.458s
user    0m4.208s    0m5.248s
sys     0m2.624s    0m2.396s

user11136 {python} ===== file_1000000_x50
real    0m16.286s
user    0m10.041s
sys     0m5.148s

jmp {python} =========== file_1000000_x50
real    0m22.845s
user    0m20.705s
sys     0m1.140s

rush {awk} ============= file_1000000_x50
real    0m44.793s
user    0m43.583s
sys     0m0.848s

##############################################

0

আপনি এগুলি প্রিন্ট ছাড়াই করতে পারেন :

awk 'BEGIN{ORS=""} {for(k=NF;k>0;--k) {print $k; if (k==1) print "\n"; else print " "}} ' file
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.