排序制表符分隔的文件


180

我有以下格式的数据:

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'

什么是正确的方法?

这是示例数据

Answers:


311

使用bash,可以达到目的:

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

注意单引号字符串前面的美元符号。您可以bash手册页ANSI-C报价部分中阅读有关它的内容


1
用于 '"'"'在别名中使用它。
Pablo A

您可以显示如何通过此分隔符在awk命令中进行排序吗?与中的一样awk '{print $0 | "sort -nr" > "outfile" }' datafile,只是将转义的制表符分隔符发送到sort命令。
Merlin

11

默认情况下,字段定界符是从非空白到空白的过渡,因此制表符应该可以正常工作。

但是,这些列的索引分别为基数1和基数0,因此您可能需要

sort -k4nr file.txt

按第4列以相反的顺序对file.txt进行数字排序。(尽管问题中的数据甚至有5个字段,所以最后一个字段将是索引5。)


4
仅当所有输入行的制表符分隔的字段之间的空格字符数相同时,这才起作用。
Lars Haugseth 09年

5

您需要在-t \后面放置一个实际的制表符,然后在shell中先按ctrl-v,再按制表符。我使用过的大多数shell都支持这种方式的文字选项卡输入。

但是要当心,因为从其他位置进行复制和粘贴通常不会保留选项卡。


这是最好的(最可移植的)答案。emacs还允许您在“引用插入”模式下执行此操作:C-q <tab>例如。我认为它^V也在纳米中。
Wyatt8740


1

通过类似的管道传送它awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'。这会将空格更改为选项卡。


@MB:我需要保持空间完整。
neversaint 2009年

1
毫无疑问,这是一种更清洁的方法,但是没有什么可以阻止您通过awk将其管道传输,将空间更改为制表符,对数据进行排序,然后再次通过awk对其进行管道传输,将这些选项卡改回空间。
Michiel Buddingh,2009年

1
如果要保留的制表符和空格混合在一起,则无法使用。
James Thompson

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

我想要Windows上针对Gnu排序的解决方案,但是以上解决方案都无法在命令行上为我工作。

使用劳埃德的线索,以下批处理文件(.bat)对我有用。

在双引号中键入制表符。

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

1
是的,这里的技巧是将其放入.bat文件中,否则将无法工作
Carlos Rendon 2014年

1

使用'general-numeric-sort'时,我在bash shell中的cygwin中的sort遇到了这个问题。如果我指定-t$'\t' -kFg,其中F是字段号,则它不起作用,但是当我同时指定-t$'\t'和时-kF,Fg(例如,-k7,7g对于第7个字段),它确实起作用。-kF,Fg没有-t$'\t'没有工作。


0

如果您只想使用制表符来使自己更轻松,请用制表符替换空格:

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

我的tr不读取文件,仅流XD。usage: tr [-Ccsu] string1 string2
Unfun Cat

1
tr string1 string2 <some-file。只要可以读取标准输入,所有内容都可以读取文件。
兰达·施瓦兹

0

Lars Haugseth的答案仅对我有效,它是从命令行执行的,如果从shell脚本执行,它将给出此错误:

排序:多字符标签“ $ \ t”

如果有人在寻找,则将其编码在shell脚本中的解决方案是

sort -t'    '

制表符位于引号之间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.