Sekmeyle ayrılmış dosyayı sıralama


180

Aşağıdaki biçimde bir veri var:

foo<tab>1.00<space>1.33<space>2.00<tab>3

Şimdi dosyayı son alana göre azalan şekilde sıralamaya çalıştım. Aşağıdaki komutları denedim ama beklediğimiz gibi sıralanmadı.

$ sort -k3nr file.txt  # apparently this sort by space as delimiter

$ sort -t"\t" -k3nr file.txt
  sort: multi-character tab `\\t'

$ sort -t "`/bin/echo '\t'`" -k3,3nr file.txt
  sort: multi-character tab `\\t'

Bunu yapmanın doğru yolu nedir?

İşte örnek veriler .

Yanıtlar:


312

Bash kullanarak , bu hile yapacaktır:

$ sort -t$'\t' -k3 -nr file.txt

Tek tırnaklı dizenin önündeki dolar işaretine dikkat edin. Bu konuyu bash man sayfasının ANSI-C Alıntı bölümlerinde okuyabilirsiniz .


2
Kullan '"'"' bir takma ad içine kullanmak.
Pablo A

awk komutunda sıralamak için bu sınırlayıcıyı nasıl geçireceğinizi gösterebilir misiniz? gibi awk '{print $0 | "sort -nr" > "outfile" }' datafilesıralama komutuna gönderilen kaçan bir sekme delimeter hariç.
Merlin

11

Varsayılan olarak alan sınırlayıcısı boş değil - boş geçiş olduğundan sekmenin iyi çalışması gerekir.

Ancak, sütunlar temel 1 ve temel 0 olarak dizine eklenir.

sort -k4nr file.txt

file.txt dosyasını 4. sütuna göre ters sırayla sayısal olarak sıralamak için. (Sorudaki verilerin 5 alanı olsa bile, son alan dizin 5 olacaktır.)


4
Bu, yalnızca sekmeyle ayrılmış alanlar arasındaki boşluk karakterlerinin sayısı tüm girdi satırları için aynı olduğunda çalışır.
Lars Haugseth

5

-T \ 'den sonra gerçek bir sekme karakteri koymanız ve bunu kabukta yapmanız için ctrl-v ve sonra sekme karakterine basmanız gerekir. Kullandığım çoğu kabuk bu değişmez sekme girişi modunu destekliyor.

Yine de dikkatli olun, çünkü başka bir yerden kopyalama ve yapıştırma genellikle sekmeleri korumaz.


Bu en iyi (en taşınabilir) cevaptır. emacs ayrıca bunu 'alıntılanan ekleme' modunda yapmanızı sağlar: C-q <tab>örneğin. Sanırım ^Vnanoda da.
Wyatt8740

3

$ Çözümü benim için çalışmadı. Ancak, sekme karakterinin kendisini komutun içine koyarak: sort -t '' -k2


1
<C-v><Tab>Sekme tuşunun kabuğunuzda otomatik tamamlama için kullanılması durumunda sekme eklemek için kullanın .
Júda Ronén

1
ANSI alıntılama $'\t'ksh, zsh ve bash olarak çalışır. Bourne kabuğu bunu desteklemiyor. Bu gönderiye
codeforester

1

gibi bir şeyden geçirin awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. Bu, boşlukları sekmelere dönüştürecektir.


@MB: Alanı sağlam tutmam gerekiyor.
neversaint

1
Kuşkusuz bunu yapmanın daha temiz bir yolu var, ancak hiçbir şey awk aracılığıyla boru oluşturmanızı, boşlukları sekmelere değiştirmenizi, verileri sıralamanızı ve ardından awk yoluyla tekrar boru oluşturmanızı, sekmeleri tekrar boşluklara dönüştürmenizi engellemiyor.
Michiel Buddingh

1
Korumak istediğiniz sekmeler ve boşlukların bir karışımı varsa, bu çalışmaz.
James Thompson

1

Genel olarak bu tür verileri tutmak, kaçınabiliyorsanız yapmak için harika bir şey değildir, çünkü insanlar her zaman sekmeleri ve boşlukları karıştırmaktadır.

Sorununuzu çözmek Perl, Python veya Ruby gibi bir betik dilinde çok basittir. İşte bazı örnek kod:

#!/usr/bin/perl -w

use strict;

my $sort_field = 2;
my $split_regex = qr{\s+};

my @data;
push @data, "7 8\t 9";
push @data, "4 5\t 6";
push @data, "1 2\t 3";

my @sorted_data = 
    map  { $_->[1] }
    sort { $a->[0] <=> $b->[0] }
    map  { [ ( split $split_regex, $_ )[$sort_field], $_ ] }
    @data;

print "unsorted\n";
print join "\n", @data, "\n";
print "sorted by $sort_field, lines split by $split_regex\n";
print join "\n", @sorted_data, "\n";

1

Windows'da Gnu sıralama için bir çözüm istedim, ancak yukarıdaki çözümlerin hiçbiri komut satırında benim için çalışmadı.

Lloyd'un ipucunu kullanarak, aşağıdaki toplu iş dosyası (.bat) benim için çalıştı.

Çift tırnak içine sekme karakterini yazın.

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

1
Evet, buradaki hile bir .bat dosyasına koyuyor, aksi takdirde işe yaramayacak
Carlos Rendon

1

Ben 'genel-sayısal-sıralama' kullanırken bir bash kabuğundaki cygwin sıralama ile bu sorunu yaşıyordu. Ben Belirtilirse -t$'\t' -kFgF alanının sayıdır, bu işi yoktu, ama ben hem belirtilen zaman -t$'\t've -kF,Fg(örneğin -k7,7g7 alan için) işe yaradı. -kF,Fgolmadan -t$'\t'işe yaramadı.


0

Yalnızca sekmeler kullanarak kendiniz için daha kolay hale getirmek istiyorsanız, boşlukları sekmelerle değiştirin:

tr " " "\t" < <file> | sort <options>

Trim dosyaları okumuyor, sadece XD akışı yapıyor. usage: tr [-Ccsu] string1 string2
Unfun Cat

1
tr string1 string2 <some-file. Her şey stdin okuyabildiği sürece bir dosyayı okuyabilir.
Randal Schwartz

0

Lars Haugseth cevabı sadece benim için komut satırından çalıştı, burada bir kabuk komut dosyasından yürütüldüğünde bu hatayı veriyor:

sort: çok karakterli sekme '$ \ t'

Bakan birisi varsa bir kabuk betiğinde kodlanmışsa çözüm

sort -t'    '

sekme karakteri tırnak arasındadır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.