2016-10-18 34 views
0

Ich habe eine Datei, die rund 500 Zeilen und 480K Spalten hat, ich bin verpflichtet, Spalten 2,3 und 4 am Ende zu verschieben. Meine Datei ist eine kommagetrennte Datei, gibt es eine schnellere Möglichkeit, dies mit awk oder sed zu arrangieren?Spalten mit awk oder sed anordnen?

+1

'Paste -d , <(ausschneiden -d, -f1,5- eingabe.txt) <(ausschneiden -d, -f2-4 eingabe.txt) ' – twalberg

+0

Schneller als was? Bearbeite deine Frage, um zu zeigen, was du bisher versucht hast, plus eine prägnante, testbare Beispieleingabe und erwartete Ausgabe. dh. stelle ein [mcve] zur Verfügung. –

Antwort

2

Sie können unter Lösung versuchen -

perl -F"," -lane 'print "@F[0]"," ","@F[4..$#F]"," ","@F[1..3]"' input.file 
+0

Es bewegt sich 3,4 und 5 zum Ende und entfernt 2. –

+0

[off-by-one-Fehler] (http://martinfowler.com/bliki/TwoHardThings.html) –

1

Sie können die Spalten einfach kopieren, das Verschieben dauert bei 480K-Spalten zu lange.

$ awk 'BEGIN{FS=OFS=","} {print $0,$2,$3,$4}' input.file > output.file 

Welche Art von Datenformat ist das?

+0

Dies sind genomische Daten, wir testen jeden einzelnen für 450K Positionen. – Mdhale

1

Testing mit 5 Feldern:

$ cat foo 
1,2,3,4,5 
a,b,c,d,e 
$ cat program.awk 
{ 
    $6=$2 OFS $3 OFS $4 OFS $1 # copy fields to the end and $1 too 
    sub(/^([^,],){4}/,"")  # remove 4 first columns 
    $1=$5 OFS $1    # catenate current $5 (was $1) to $1 
    NF=4      # reduce NF 
} 1        # print 

Run it:

$ awk -f program.awk FS=, OFS=, foo 
1,5,2,3,4 
a,e,b,c,d 

So theoretisch sollte diese Arbeit:

{ 
    $480001=$2 OFS $3 OFS $4 OFS $1 
    sub(/^([^,],){4}/,"") 
    $1=$480000 OFS $1 
    NF=479999 
} 1 

EDIT: es funktioniert hat.

+1

Mein Verständnis ist es 480.000 Spalten nicht 480. – karakfa

1

Vielleicht Perl:

perl -F, -lane 'print join(",", @F[0,4..$#F,1,2,3])' file 

oder

perl -F, -lane '@x = splice @F, 1, 3; print join(",", @F, @x)' file 

Ein anderer Ansatz: Reguläre Ausdrücke

perl -lpe 's/^([^,]+)(,[^,]+,[^,]+,[^,]+)(.*)/$1$3$2/' file 

Zeit es mit einer 500 Zeilendatei, enthält jede Zeile 480.000 Felder

$ time perl -F, -lane 'print join(",", @F[0,4..$#F,1,2,3])' file.csv > file2.csv 
40.13user 1.11system 0:43.92elapsed 93%CPU (0avgtext+0avgdata 67960maxresident)k 
0inputs+3172752outputs (0major+16088minor)pagefaults 0swaps 

$ time perl -F, -lane '@x = splice @F, 1, 3; print join(",", @F, @x)' file.csv > file2.csv 
34.82user 1.18system 0:38.47elapsed 93%CPU (0avgtext+0avgdata 52900maxresident)k 
0inputs+3172752outputs (0major+12301minor)pagefaults 0swaps 

Und reine Textmanipulation ist der Gewinner

$ time perl -lpe 's/^([^,]+)(,[^,]+,[^,]+,[^,]+)(.*)/$1$3$2/' file.csv > file2.csv 
4.63user 1.36system 0:20.81elapsed 28%CPU (0avgtext+0avgdata 20612maxresident)k 
0inputs+3172752outputs (0major+149866minor)pagefaults 0swaps 
+0

Ich habe am Ende ein Perl-Skript schreiben, um dies zu tun, aber ich kann dies auch überprüfen. – Mdhale

+0

Letzterer für einen Datensatz mit 480000 Cols, die mit "time" getaktet wurden, war im Durchschnitt etwas schneller. –

1

Eine andere Technik, nur bash:

while IFS=, read -r a b c d e; do 
    echo "$a,$e,$b,$c,$d" 
done < file 
Verwandte Themen