UNIX排序命令如何排序一个非常大的文件?

时间:2009-05-30 16:18:32

标签: shell sorting

UNIX sort命令可以对这样一个非常大的文件进行排序:

sort large_file

如何实施排序算法?

为什么它不会导致过多的内存消耗?

8 个答案:

答案 0 :(得分:105)

Algorithmic details of UNIX Sort command表示Unix Sort使用外部R-Way合并排序算法。链接进入更多细节,但实质上它将输入分成较小的部分(适合内存),然后在结尾处将每个部分合并在一起。

答案 1 :(得分:39)

sort命令将工作数据存储在临时磁盘文件中(通常在/tmp中)。

答案 2 :(得分:13)

警告:此脚本每个块启动一个shell,对于非常大的文件,这可能是数百个。


这是我为此目的编写的脚本。在4处理器的机器上,它将排序性能提高了100%!

#! /bin/ksh

MAX_LINES_PER_CHUNK=1000000
ORIGINAL_FILE=$1
SORTED_FILE=$2
CHUNK_FILE_PREFIX=$ORIGINAL_FILE.split.
SORTED_CHUNK_FILES=$CHUNK_FILE_PREFIX*.sorted

usage ()
{
     echo Parallel sort
     echo usage: psort file1 file2
     echo Sorts text file file1 and stores the output in file2
     echo Note: file1 will be split in chunks up to $MAX_LINES_PER_CHUNK lines
     echo  and each chunk will be sorted in parallel
}

# test if we have two arguments on the command line
if [ $# != 2 ]
then
    usage
    exit
fi

#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null
rm -f $SORTED_FILE

#Splitting $ORIGINAL_FILE into chunks ...
split -l $MAX_LINES_PER_CHUNK $ORIGINAL_FILE $CHUNK_FILE_PREFIX

for file in $CHUNK_FILE_PREFIX*
do
    sort $file > $file.sorted &
done
wait

#Merging chunks to $SORTED_FILE ...
sort -m $SORTED_CHUNK_FILES > $SORTED_FILE

#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null

另见: “Sorting large files faster with a shell script

答案 3 :(得分:11)

我不熟悉该程序,但我想这是通过外部排序完成的(大部分问题都保存在临时文件中,而问题的相对较小部分一次保存在内存中)。请参阅Donald Knuth的The Art of Computer Programming, Vol. 3 Sorting and Searching, Section 5.4,深入讨论该主题。

答案 4 :(得分:11)

#!/bin/bash

usage ()
{
    echo Parallel sort
    echo usage: psort file1 file2
    echo Sorts text file file1 and stores the output in file2
}

# test if we have two arguments on the command line
if [ $# != 2 ]
then
    usage
    exit
fi

pv $1 | parallel --pipe --files sort -S512M | parallel -Xj1 sort -S1024M -m {} ';' rm {} > $2

答案 5 :(得分:5)

仔细查看排序选项以加快性能并了解它对您的计算机和问题的影响。 Ubuntu的关键参数是

  • 临时文件的位置-T directory_name
  • 要使用的内存量-S N%(使用的所有内存的N%,越多越好但是 避免过度订阅导致交换到磁盘。您可以像“-80%”一样使用它来使用80%的可用RAM,或者使用“-S 2G”来使用2 GB RAM。)

提问者问“为什么没有高内存使用率?”答案来自历史,旧的unix机器很小,默认的内存大小设置得很小。为您的工作负载调整尽可能大的数量,以大大提高排序性能。将工作目录设置为最快设备上的某个位置,该位置具有足够的空间以容纳至少1.25 *正在排序的文件的大小。

答案 6 :(得分:0)

如何使用-T选项对大文件进行排序

我必须对大文件的第七列进行排序。

我正在使用:

grep vdd  "file name" | sort -nk 7 |

我遇到以下错误:

******sort: write failed: /tmp/sort1hc37c: No space left on device******

然后我使用-T选项,如下所示:

grep vdda  "file name" | sort -nk 7  -T /dev/null/ |

答案 7 :(得分:-3)

内存应该不是问题 - 排序已经解决了这个问题。如果你想最佳地使用你的多核CPU,我已经在一个小脚本中实现了这一点(类似于你可能在网上找到的,但比大多数更简单/更清洁;))。

#!/bin/bash
# Usage: psort filename <chunksize> <threads>
# In this example a the file largefile is split into chunks of 20 MB.
# The part are sorted in 4 simultaneous threads before getting merged.
# 
# psort largefile.txt 20m 4    
#
# by h.p.
split -b $2 $1 $1.part
suffix=sorttemp.`date +%s`
nthreads=$3
i=0
for fname in `ls *$1.part*`
do
    let i++
    sort $fname > $fname.$suffix &
    mres=$(($i % $nthreads))
    test "$mres" -eq 0 && wait
done
wait
sort -m *.$suffix 
rm $1.part*