web-dev-qa-db-ja.com

タブ区切りファイルの並べ替え

次の形式のデータがあります。

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

ここで、最後のフィールドに基づいてファイルを並べ替えようとしました。次のコマンドを試しましたが、予想どおりにソートされませんでした。

$ 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'

それを行う正しい方法は何ですか?

サンプルデータ です。

163
neversaint

bashを使用して、これはトリックを行います:

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

一重引用符で囲まれた文字列の前にドル記号があることに注意してください。これについては、bashmanページの ANSI-C引用セクション で読むことができます。

291
Lars Haugseth

デフォルトでは、フィールドの区切り文字は空白から空白への移行ではないため、タブは正常に機能します。

ただし、列のインデックスはベース1およびベース0であるため、おそらく

sort -k4nr file.txt

file.txtを列4で逆順に並べ替えます。 (質問のデータには5つのフィールドさえあるので、最後のフィールドはインデックス5になります。)

10
laalto

実際のタブ文字を-t \の後に配置する必要があります。これを行うには、シェルでctrl-vを押してからタブ文字を押します。私が使用したほとんどのシェルは、このモードのリテラルタブエントリをサポートしています。

ただし、別の場所からコピーして貼り付けると一般にタブが保持されないため、注意してください。

4
Brian Carlsen

$の解決策はうまくいきませんでした。ただし、実際にコマンドにタブ文字自体を入れることで、次のようになりました:sort -t '' -k2

3
Lloyd

awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'のようなものにパイプします。これにより、スペースがタブに変更されます。

1

一般に、このようなデータを保持することは、避けることができる場合、実行するのは素晴らしいことではありません。なぜなら、人々は常にタブとスペースを混乱させるからです。

Perl、Python、Rubyなどのスクリプト言語では、問題の解決は非常に簡単です。コードの例を次に示します。

#!/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
James Thompson

WindowsでGnuソートのソリューションが必要でしたが、上記のソリューションのいずれもコマンドラインで機能しませんでした。

ロイドの手がかりを使用して、次のバッチファイル(.bat)が機能しました。

二重引用符内にタブ文字を入力します。

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt
1

'general-numeric-sort'を使用している場合、bashシェルのcygwinでのソートでこの問題が発生していました。 -t$'\t' -kFg(Fはフィールド番号)を指定した場合、機能しませんでしたが、-t$'\t'-kF,Fgの両方を指定した場合(たとえば、7番目のフィールドに-k7,7g)うまくいきました。 -kF,Fgなしの-t$'\t'は機能しませんでした。

0
Danny

タブのみを使用して自分で簡単にしたい場合は、スペースをタブに置き換えます。

tr " " "\t" < <file> | sort <options>
0
The Unfun Cat