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

时间:2015-05-04 06:24:02

标签: linux bash shell sorting awk

有没有一种很好的方法来对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

     

a_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

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

2 个答案:

答案 0 :(得分:3)

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

以下是所需路径名排序层次结构的最终解决方案(dotfile dirs&gt;普通dirs&gt; dotfile文件&gt;普通文件):

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

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

类似地,为了排序任何其他路径名输出源:

findtool | LC_ALL=C sort

答案 1 :(得分:0)

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

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
"

有一点需要注意:还有其他项目会遗漏,例如链接和设备。