文件夹下文件名正确排序问题



有时候需要将文件名按照数字大小排序,而不是按照字母顺序排序,例如:


Traditional Sort
Alphanum
1000X Radonius Maximus
10X Radonius
200X Radonius
20X Radonius
20X Radonius Prime
30X Radonius
40X Radonius
Allegia 50 Clasteron
Allegia 500 Clasteron
Allegia 50B Clasteron
Allegia 51 Clasteron
Allegia 6R Clasteron
Alpha 100
Alpha 2
Alpha 200
Alpha 2A
Alpha 2A-8000
Alpha 2A-900
Callisto Morphamax
Callisto Morphamax 500
Callisto Morphamax 5000
Callisto Morphamax 600
Callisto Morphamax 6000 SE
Callisto Morphamax 6000 SE2
Callisto Morphamax 700
Callisto Morphamax 7000
Xiph Xlater 10000
Xiph Xlater 2000
Xiph Xlater 300
Xiph Xlater 40
Xiph Xlater 5
Xiph Xlater 50
Xiph Xlater 500
Xiph Xlater 5000
Xiph Xlater 58
        

10X Radonius
20X Radonius
20X Radonius Prime
30X Radonius
40X Radonius
200X Radonius
1000X Radonius Maximus
Allegia 6R Clasteron
Allegia 50 Clasteron
Allegia 50B Clasteron
Allegia 51 Clasteron
Allegia 500 Clasteron
Alpha 2
Alpha 2A
Alpha 2A-900
Alpha 2A-8000
Alpha 100
Alpha 200
Callisto Morphamax
Callisto Morphamax 500
Callisto Morphamax 600
Callisto Morphamax 700
Callisto Morphamax 5000
Callisto Morphamax 6000 SE
Callisto Morphamax 6000 SE2
Callisto Morphamax 7000
Xiph Xlater 5
Xiph Xlater 40
Xiph Xlater 50
Xiph Xlater 58
Xiph Xlater 300
Xiph Xlater 500
Xiph Xlater 2000
Xiph Xlater 5000
Xiph Xlater 10000
        
使用:

private void button1_Click_1(object sender, EventArgs e)
        {
            this.treeView1.Nodes.Clear();
            
           if( this.folderBrowserDialog1.ShowDialog()==DialogResult.OK )
           {
               this.label6.Text =this.folderBrowserDialog1.SelectedPath;
               workpath = this.folderBrowserDialog1.SelectedPath;
               DirectoryInfo dir = new DirectoryInfo(workpath);
               FileInfo[] arrFi = dir.GetFiles("*.*");
               //FileInfo[] files = dir.GetFiles();
               SortAsFileName(ref arrFi);
               for (int i = 0; i < arrFi.Length; i++)
               {
                   this.treeView1.Nodes.Add(arrFi[i].Name);
               }
               
           }
        }
        private void SortAsFileName(ref FileInfo[] arrFi)
        {
            AlphanumComparator alph = new AlphanumComparator();
            //Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return x.Name.CompareTo(y.Name); });
            Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return alph.Compare(x.Name, y.Name); });
        }
智能排序类:

/*
 * The Alphanum Algorithm is an improved sorting algorithm for strings
 * containing numbers.  Instead of sorting numbers in ASCII order like
 * a standard sort, this algorithm sorts numbers in numeric order.
 *
 * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
 *
 * Based on the Java implementation of Dave Koelle's Alphanum algorithm.
 * Contributed by Jonathan Ruckwood <jonathan.ruckwood@gmail.com>
 *
 * Adapted by Dominik Hurnaus <dominik.hurnaus@gmail.com> to
 *   - correctly sort words where one word starts with another word
 *   - have slightly better performance
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
using System;
using System.Collections;
using System.Text;
/*
 * Please compare against the latest Java version at http://www.DaveKoelle.com
 * to see the most recent modifications
 */
namespace AlphanumComparator
{
    public class AlphanumComparator : IComparer
    {
        private enum ChunkType {Alphanumeric, Numeric};
        private bool InChunk(char ch, char otherCh)
        {
            ChunkType type = ChunkType.Alphanumeric;
            if (char.IsDigit(otherCh))
            {
                type = ChunkType.Numeric;
            }
            if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
                || (type == ChunkType.Numeric && !char.IsDigit(ch)))
            {
                return false;
            }
            return true;
        }
        public int Compare(object x, object y)
        {
            String s1 = x as string;
            String s2 = y as string;
            if (s1 == null || s2 == null)
            {
                return 0;
            }
            int thisMarker = 0, thisNumericChunk = 0;
            int thatMarker = 0, thatNumericChunk = 0;
            while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
            {
                if (thisMarker >= s1.Length)
                {
                    return -1;
                }
                else if (thatMarker >= s2.Length)
                {
                    return 1;
                }
                char thisCh = s1[thisMarker];
                char thatCh = s2[thatMarker];
                StringBuilder thisChunk = new StringBuilder();
                StringBuilder thatChunk = new StringBuilder();
                while ((thisMarker < s1.Length) && (thisChunk.Length==0 ||InChunk(thisCh, thisChunk[0])))
                {
                    thisChunk.Append(thisCh);
                    thisMarker++;
                    if (thisMarker < s1.Length)
                    {
                        thisCh = s1[thisMarker];
                    }
                }
                while ((thatMarker < s2.Length) && (thatChunk.Length==0 ||InChunk(thatCh, thatChunk[0])))
                {
                    thatChunk.Append(thatCh);
                    thatMarker++;
                    if (thatMarker < s2.Length)
                    {
                        thatCh = s2[thatMarker];
                    }
                }
                int result = 0;
                // If both chunks contain numeric characters, sort them numerically
                if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
                {
                    thisNumericChunk = Convert.ToInt32(thisChunk.ToString());
                    thatNumericChunk = Convert.ToInt32(thatChunk.ToString());
                    if (thisNumericChunk < thatNumericChunk)
                    {
                        result = -1;
                    }
                    if (thisNumericChunk > thatNumericChunk)
                    {
                        result = 1;
                    }
                }
                else
                {
                    result = thisChunk.ToString().CompareTo(thatChunk.ToString());
                }
                if (result != 0)
                {
                    return result;
                }
            }
            return 0;
        }
    }
}
参考:http://www.davekoelle.com/alphanum.html

<think>好的,我现在需要帮助用户解决如何使用du命令统计文件夹及子文件夹大小并进行排序问题。首先,我应该回忆一下du命令的基本用法相关参数。记得du是用于计算目录大小的工具,结合sort命令可以进行排序。 用户提到要统计文件夹及其子文件夹的大小,并排序。首先,我需要确定du命令中哪个参数可以控制子目录的深度。根据之前的引用,比如引用[3]中提到的du -hd1,这里-d1表示只显示一级子目录。但用户需要包括子文件夹,可能需要调整这个参数。或者,如果用户希望显示所有子目录,可能需要省略-d参数,或者根据需求设置同的深度。 过用户的问题是要计算文件夹及其子文件夹的大小,可能是指每个子文件夹各自的大小,包括它们的子文件夹。这时候,可能需要使用--max-depth参数。比如,du -h --max-depth=2会显示当前目录下两级子目录的大小。但用户可能需要所有层级的文件夹,或者只显示每个直接子文件夹的总大小。需要进一步明确。 过根据用户的问题描述,用户可能希望列出所有文件夹及其子文件夹的大小,并按大小排序过这可能会有很多结果,所以或许用户希望的是每个目录的汇总大小,包括其子目录。这时候,默认的du命令会递归显示所有子目录,但这样输出会很多。所以可能需要结合适当的--max-depth参数来控制显示的层级。 例如,如果用户想查看当前目录下所有子目录(包括子目录的子目录)的大小并排序,那么可能需要使用--max-depth,或者设置较大的层级。但这样输出会非常多,可能太方便。或者用户可能只需要当前目录下的直接子文件夹的大小,包括它们各自子文件夹的总,这时使用--max-depth=1。 比如引用[3]中的例子是du -hd1,也就是--max-depth=1,显示一级子目录的大小。然后通过管道传给sort -hr进行逆序排序。但用户的问题中提到“文件夹及其子文件夹”,可能需要更深入的处理。 这时候,可能需要明确用户的意图:是否希望列出所有层级的子文件夹的大小并排序,还是只显示每个直接子目录的总大小(包含它们自己的子目录)并按大小排序? 通常,如果用户想要查看某个目录下各个子目录的总大小,并按大小排序,常用的方法是使用du -sh * | sort -hr,其中-s表示汇总每个参数的总大小(即每个子目录的总大小),-h以人类可读格式显示。然后通过sort -hr进行逆序排序。 但根据引用中的例子,比如引用[3]使用的是du -hd1,也就是显示当前目录下一级子目录的大小,以人类可读格式,然后通过管道传给sort -hr。而如果用户需要包括所有子文件夹,可能需要调整--max-depth的值,或者限制深度,但这样结果会很多,可能太适合排序。 例如,假设用户想查看当前目录下所有子文件夹及其子子文件夹的大小,并按大小排序。这时候,直接运行du -h然后sort可能会得到很多条目,但用户可能更关注较大的目录,因此可能需要结合head来显示前几个结果。过用户的问题中没有提到需要限制数量,只提到排序。 所以可能的解决方案是: 1. 使用du命令递归计算每个目录的大小,并显示所有目录的大小。 2. 通过sort命令进行排序。 但这样可能会有太多结果,所以更合理的做法是让用户指定目录层级。例如,如果用户想查看当前目录下所有子目录(包括子目录的子目录)的大小并按大小排序,可以运行: du -h | sort -hr 但这样每个目录都会被列出,包括嵌套的子目录,这可能导致输出冗长。所以可能用户更希望只查看当前目录下的直接子目录的总大小,这时候使用-s参数,或者--max-depth=1。 比如,正确的命令应该是: du -sh * | sort -hr 这里,-s表示汇总每个参数的总大小,-h是human-readable。*表示当前目录下的所有文件目录,但du会为每个目录显示其总大小,文件则显示其自身大小。然后通过sort -hr进行逆序排序。 或者,如果用户希望只处理目录,包括文件,可能需要结合find命令,比如: du -sh $(find . -maxdepth 1 -type d) | sort -hr 但这样可能会有问题,因为如果目录名包含空格的话。更安全的方式是使用find的-exec或者通过管道来处理。 过根据引用中的例子,比如引用[2]中的例子使用了find来定位文件,然后结合dusort。但用户的问题是关于文件夹的,所以可能需要调整。 回到用户的问题,用户想统计文件夹及其子文件夹的大小并排序。可能用户希望的是每个子文件夹的总大小,包括它们的子文件夹,然后进行排序。所以正确的做法是: 进入目标目录,然后执行: du -h --max-depth=1 | sort -hr 这里的--max-depth=1会显示当前目录下的一级子目录的大小(包括它们所有子目录的大小),然后排序。例如,如果用户想统计/home/user下的各个子目录的大小,可以: cd /home/user du -h --max-depth=1 | sort -hr 这样就能看到每个子目录的总大小,并按从大到小排序。 或者,如果用户希望包括所有层级的子目录,那么可以省略--max-depth参数,但这样结果会很多,可能太方便。因此,通常推荐使用--max-depth来控制显示的层级。 另外,引用[4]中提到语法中的--max-depth参数,所以用户需要根据需求设置这个参数。例如,要查看当前目录下的所有子目录(包括子目录的子目录)的大小,可以设置--max-depth为更大的数值,或者设置,但这样输出会很长。 总结用户的需求,可能的解决步骤是: 1. 使用du命令计算目录大小,参数包括-h(人类可读)适当的--max-depth。 2. 通过管道将结果传给sort命令,使用-h(人类可读的数字排序-r(逆序)参数。 3. 可能的组合命令如:du -h --max-depth=2 | sort -hr 但需要根据具体情况调整--max-depth的值。如果用户想要当前目录下的所有子目录(包括嵌套的子目录)的大小,可能需要限制--max-depth,但这样输出太多,所以更可能的正确命令是针对特定目录层级的汇总。 例如,假设用户想查看当前目录下所有直接子文件夹的大小(包括它们的子文件夹),并按大小排序正确的命令是: du -sh * | sort -hr 或者,如果当前目录下有很多文件,而用户只关心目录,可以结合find命令: du -sh $(find . -maxdepth 1 -type d) | sort -hr 或者更安全的: find . -maxdepth 1 -type d -exec du -sh {} + | sort -hr 这可以避免文件名中的空格等问题过根据引用中的例子,比如引用[3]中的du -hd1 | sort -hr,这里使用的是-d 1,相当于--max-depth=1,显示当前目录下的一级子目录的大小,并以人类可读格式输出,然后排序。这种方法可能更直接。 所以正确的命令应该是: du -h --max-depth=1 | sort -hr 或者简写为: du -hd1 | sort -hr 这样就能得到当前目录下一级子目录的大小,并按从大到小排序,包括它们的子文件夹的大小总。 如果用户需要处理特定目录,而是当前目录,可以在du命令后加上路径,例如: du -h --max-depth=1 /path/to/directory | sort -hr 这样就能统计该目录下的一级子目录的大小并排序。 总结,用户的问题的解决步骤应该是: 1. 使用du命令的-h参数以人类可读格式显示大小。 2. 使用--max-depth参数指定要显示的目录层级,例如--max-depth=1表示只显示当前目录的直接子目录。 3. 使用sort命令的-h-r参数进行逆序排序。 4. 组合命令如:du -h --max-depth=1 | sort -hr 另外,需要注意权限问题,如果用户没有权限访问某些子目录,du命令可能会报错,这时可能需要使用sudo,但需要谨慎处理。 最后,验证命令是否正确。例如,在终端中运行: cd 到目标目录 du -hd1 | sort -hr 这会显示当前目录下所有一级子目录的大小,并按从大到小排序,这正是用户需要的。</think>要统计文件夹及其子文件夹的大小并按大小排序,可以按以下步骤操作: ### 操作步骤 1. **进入目标目录** ```bash cd /path/to/your/directory ``` 2. **执行组合命令** ```bash du -h --max-depth=1 | sort -hr ``` - `du -h --max-depth=1`: - `-h` 以人类可读格式(KB/MB/GB)显示大小 - `--max-depth=1` 仅统计直接子目录的总大小(包含其所有子文件夹)[^3][^4] - `| sort -hr`: - `-h` 按人类可读的数值排序 - `-r` 逆序排列(从大到小) 3. **示例输出** ``` 12G ./Documents 8.4G ./Downloads 3.2G ./Pictures 1.1G ./Music ``` ### 扩展场景 - **统计所有层级的子目录** 移除 `--max-depth=1`,但结果会包含嵌套子目录: ```bash du -h | sort -hr ``` - **仅统计特定深度的子目录** 修改 `--max-depth` 值,例如统计两级子目录: ```bash du -h --max-depth=2 | sort -hr ``` - **排除文件仅统计目录** 结合 `find` 命令过滤目录: ```bash find . -maxdepth 1 -type d -exec du -sh {} + | sort -hr ``` ### 引用说明 `du` 与 `sort` 的组合是处理目录大小排序的标准方法[^1]。通过调整 `--max-depth` 参数可灵活控制统计范围[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值