【问题标题】:Sorting directory contents (including hidden files) by name in the shell在 shell 中按名称对目录内容(包括隐藏文件)进行排序
【发布时间】:2015-05-04 06:24:01
【问题描述】:

有没有一种在 shell 中对目录内容(包括隐藏文件)进行排序的好方法?基本上我希望能够在我的 GUI 文件管理器中完成 ls 目录。在一个典型的目录中,输出是这样的:

.a_hidden_​​dir

.b_hidden_​​dir

.c_hidden_​​dir

a_dir

b_dir

c_dir

.a_hidden_​​file

.b_hidden_​​file

.c_hidden_​​file

一个文件

b_file

c_file

当然ls--group-directories-first 选项,但这只是让我们了解其中的一部分,因为sort 忽略了前导.,它不会将隐藏文件排序到顶部。

我希望能够以这种方式对来自lsfind 或其他路径列表的输出进行排序。有谁知道这样做的好方法 - 也许是sort -k KEYDEF

现在我正在做这样的事情(它假设目录名称有一个斜杠附加到它们):

pathsort(){
    input=$(cat)
    (
        awk '/^\..+\/$/' <<<"$input" | sort
        awk '/^[^.].+\/$/' <<<"$input" | sort
        awk '/^\..+[^/]$/' <<<"$input" | sort
        awk '/^[^.].+[^/]$/' <<<"$input" | sort
    ) | sed 's/\/$//'
}

\ls -Ap | pathsort

上面的代码完成了工作,但远非理想。请告诉我有更好的方法...

【问题讨论】:

  • 发布你期望的输出。
  • ls -la 不起作用?
  • 可以通过运行\ls -Ap获取示例输入。预期的示例输出在上面第一个引用的文本块中(以 .a_hidden_​​dir 开头)。 ls -la 当然可以“工作”,但我正在尝试对输出进行排序,隐藏的东西在顶部,就像在文件管理器中一样。我要它排序隐藏目录、目录、隐藏文件、文件。
  • 您是否尝试过在环境中设置 LANG=C 以便按 C 顺序进行排序,其中带前导点的名称出现在大多数其他名称之前。
  • @JonathanLeffler 啊,谢谢,太简单了!我以前使用 LC_ALL=C 和 sort 进行可重现的构建,但不知道 LANG=C。 LANG=C \ls -A --group-directories-first 正是我所需要的......而我在这里杰瑞操纵了一些可怕的装置。再次感谢!

标签: linux bash shell sorting awk


【解决方案1】:

Jonathan Lefflercomment中提出了一个简单实用的解决方案:设置本地环境变量LANG=C。在我的系统上,默认的LANG=en_US.UTF-8 会导致不受欢迎的路径名排序特征。 C 显然是指使用 ASCII 字符集进行字节字符排序。设置LANG=C 的结果是'dotfiles'(包括目录)被排序到顶部。注意LC_ALL=C 也可能有用,因为LC_ALLLANG 和其他LC_* 变量的超集。总而言之,如果您想要一致的排序体验,强烈建议您将语言环境设置为 C 来排序命令。

这是所需路径名排序层次结构的最终解决方案(点文件目录>普通目录>点文件文件>普通文件):

LC_ALL=C ls -A --group-directories-first

注意:这也包括文件和目录的符号链接

类似地用于对任何其他路径名输出源进行排序:

findtool | LC_ALL=C sort

【讨论】:

    【解决方案2】:

    有趣的是,我认为对目录进行排序是最简单的:

    ls -1d .*/; ls -1d */
    

    文件很难从目录中分离出来,你需要使用find:

    (find . -maxdepth 1 -type f -name '.*' -printf '%P\n' | sort); (find . -maxdepth 1 -type f -not -name '.*' -printf '%P\n' | sort)
    

    把整个事情放在一起:

    alias lss="
        ls -1d .*/;   # Hidden directories
        ls -1d */;    # Normal directories
        find . -maxdepth 1 -type f -name '.*' -printf '%P\n' | sort;
                      # Hidden files
        find . -maxdepth 1 -type f -not -name '.*' -printf '%P\n' | sort
                      # Normal files
    "
    

    一个警告:这会遗漏其他项目,例如链接和设备。

    【讨论】:

    • 你的 lsd 看起来不错。我用 lsd (find -L -maxdepth 1 -type d -name '.*' -printf '%P\n' | sort; find -L -maxdepth 1 -mindepth 1 -type d ! -name '.*' -printf '%P\n' | sort) 和 lsf (find -L -maxdepth 1 -type f -name '.*' -printf '%P\n' | sort; find -L -maxdepth 1 -type f ! -name '.*' -printf '%P\n' | sort) 做了一些与第二个例子非常相似的事情。 -L 将捕获指向目录/文件的链接。我也希望能够对其他输出进行排序......结果证明这让事情变得非常复杂。您可以通过LC_ALL=C \ls -A --g 获得所需的排序。 :P
    • 是的,也许您应该通过更新回答您自己的问题并将其标记为已回答。这样其他可能有类似问题的人就会看到您的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 2011-08-20
    相关资源
    最近更新 更多