【问题标题】:Any robust method to sort file columns?任何对文件列进行排序的可靠方法?
【发布时间】:2012-04-16 16:55:39
【问题描述】:

我有一个 Perl 脚本,它使用 system 调用对 tsv 文件进行排序:

system("sort -k8 -r -n -t \$'\t' in.txt > out.txt");

它在 CentOS 和 SUSE Linux 中运行良好。但是在 Ubuntu 中,它给出了一个错误:

sort: multi-character tab `$\t'

似乎不同操作系统的问题对报价的解释不同。你有一个简单但更健壮的方法来在 Perl 中对 tsv 文件进行排序吗?

【问题讨论】:

  • 我咬一口:你为什么使用系统排序命令而不是内部 Perl 排序命令? Perl 排序将更快、更高效,并且适用于所有操作系统——甚至是 Windows。
  • 大卫,我正在考虑将文件加载到数组中,对其进行排序,然后将其写出。这很麻烦。此外,对文件进行排序不是我程序中的瓶颈,所以我只是采取简单的方法。或者你有简单有效的方法吗?谢谢。
  • 区别在于ubuntu的/bin/sh是dash,而不是bash。 $'\t' 是一个bashism。
  • @DavidW。是什么让您认为 perl 排序会更快?系统排序非常快,并且不限于内存数据集大小。 Perl 不是速度恶魔,与以较低抽象级别编写的程序相比,它是一个具有大量开销的 HLL。
  • @dberhur 有几篇关于speed of Perl's sorting algorithm vs. the command line sort 的帖子。如果 OP 针对这种特殊情况编写了自己的 C 排序程序,它会比 Perl 更快,但 Unix 排序命令是为了灵活性而编写的。与我认为的简单编译的 Unix 系统命令相比,Perl 的速度让我感到惊讶。

标签: perl sorting system-calls tsv


【解决方案1】:

通常,您会使用system 的数组调用来避免shell,但是您在命令中有I/O 重定向,这很难处理。 OTOH,sort 允许您使用-o 指定输出文件,命名文件可以是输入之一(虽然它不会在这里):

my @cmd = ( "sort", "-k8", "-rn", "-t", "\t", "-o", "out.txt", "in.txt" );

system(@cmd);

shell 没有被调用;选项卡没有损坏。我将-r-n 选项合二为一;如果您愿意,可以将它们分开,或者(在紧要关头)在-k8 选项之后添加它们。

【讨论】:

  • 漂亮,这种方式很适合这种排序命令。但是,如果我想从另一个输出管道输入输入会发生什么?创建另一个临时文件是唯一的选择吗?另外,如果命令没有输出选项并且我不能使用重定向(>)会发生什么?对这2个案例有什么建议吗?非常感谢。
  • 如果你想通过管道传送到sort 命令(或两者),或者如果目标命令没有方便的-o-like 选项,你必须更加努力您的 IPC(进程间通信)机制,并且您必须放弃 system 并使用(在 Unix 上)forkexec 等加上管道。可以办到;不过,建议您查看 Perl 中的 IPC 模块,以节省您的精力。另一个主要的替代方案是 David W 建议的:在 Perl 本身中进行排序。您需要知道自己在做什么,但这也是可行的,并且可以避免临时文件。
  • 我得到“输入文件指定了两次。” cygwin 出错
  • @arjun:你什么时候做的?我的答案中显示的命令似乎不太可能产生该错误。
  • 实际上我是在使用 eclipse 调试并得到错误。我不知道为什么?从 cywin 运行时,您的命令没有问题/错误。
猜你喜欢
  • 2012-06-01
  • 1970-01-01
  • 2018-07-03
  • 2014-06-21
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 2015-12-24
  • 1970-01-01
相关资源
最近更新 更多