在 shell 中按名称对目录内容(包括隐藏文件)进行排序

Six*_*Six 5 linux sorting bash shell awk

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

.a_hidden_​​dir

.b_hidden_​​dir

.c_hidden_​​dir

目录

b_目录

c_目录

.a_隐藏文件

.b_隐藏文件

.c_隐藏文件

一份文件

b_文件

c_文件

当然ls有这个--group-directories-first选项,但这只能让我们完成部分工作,因为sort忽略了前导.,它不会将隐藏文件排序到顶部。

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

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

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

\ls -Ap | pathsort
Run Code Online (Sandbox Code Playgroud)

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

Six*_*Six 5

Jonathan Leffler在评论中提出了一个简单实用的解决方案:设置本地环境变量LANG=C。在我的系统上,默认值LANG=en_US.UTF-8会导致不良的路径名排序特性。C 显然是指使用 ASCII 字符集按字节进行字符排序。设置的结果LANG=C是“点文件”(包括目录)被排序到顶部。值得注意的是,LC_ALL=C也可以使用它,它的LC_ALL超集是LANG和 其他LC_*。总而言之,如果您想要一致的排序体验,强烈建议将排序命令的区域设置设置为 C。

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

LC_ALL=C ls -A --group-directories-first
Run Code Online (Sandbox Code Playgroud)

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

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

findtool | LC_ALL=C sort
Run Code Online (Sandbox Code Playgroud)