有没有一种很好的方法来对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忽略了前导.,它没有将隐藏文件排在顶部。
我希望能够以这种方式对ls,find或其他路径列表中的输出进行排序。 有谁知道这样做的好方法 - 也许sort -k KEYDEF?
现在我正在做这样的事情(它假设目录名称有一个斜杠附加到它们):
pathsort(){
input=$(cat)
(
awk '/^\..+\/$/' <<
awk '/^[^.].+\/$/' <<
awk '/^\..+[^/]$/' <<
awk '/^[^.].+[^/]$/' <<
) | 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正是我所需要的......而且我在这里操纵一些可怕的装置。 再次感谢!
对于ls和sort,您可以使用LC_ALL代替LANG,或者使用LANG。 你也应该能够使用LC_COLLATE; 这是最精确的。
Jonathan Leffler在评论中提出了一个简单而实用的解决方案:设置本地环境变量LANG=C。在我的系统上,默认的LANG=en_US.UTF-8会导致不合需要的路径名排序特征。 C显然是指使用ASCII字符集的字节字符排序。设置LANG=C的结果是'dotfiles'(包括目录)被排序到顶部。注意也可以使用LC_ALL=C,因为LC_ALL是LANG和其他LC_*变量的超集。总而言之,如果您想要一致的排序体验,强烈建议将语言环境设置为C以排序命令。
这是所需路径名排序层次结构的最终解决方案(dotfile dirs>普通dirs> dotfile文件>普通文件):
LC_ALL=C ls -A --group-directories-first
注意:这还包括文件和目录的符号链接
类似地,为了排序任何其他路径名输出源:
findtool | LC_ALL=C sort
有趣的是,我认为对目录进行排序是最简单的:
ls -1d .*/; ls -1d */
文件更难与目录分离,您需要使用find:
(find . -maxdepth 1 -type f -name '.*' -printf '%P
' | sort); (find . -maxdepth 1 -type f -not -name '.*' -printf '%P
' | sort)
把整个事情放在一起:
alias lss="
ls -1d .*/; # Hidden directories
ls -1d */; # Normal directories
find . -maxdepth 1 -type f -name '.*' -printf '%P
' | sort;
# Hidden files
find . -maxdepth 1 -type f -not -name '.*' -printf '%P
' | sort
# Normal files
"
一个警告:还有其他一些项目会丢失,比如链接和设备。
你的lsd看起来不错。 我使用lsd (find -L -maxdepth 1 -type d -name '.*' -printf '%P
' | sort; find -L -maxdepth 1 -mindepth 1 -type d ! -name '.*' -printf '%P
' | sort)和lsf (find -L -maxdepth 1 -type f -name '.*' -printf '%P
' | sort; find -L -maxdepth 1 -type f ! -name '.*' -printf '%P
' | sort)完成了与第二个示例非常相似的操作。 -L将捕获到dirs /文件的链接。 我希望能够对其他输出进行排序......结果证明这是一件非常复杂的事情。 您可以通过LC_ALL=C \ls -A --g获得所需的排序。:P
是的,也许您应该通过更新回答您自己的问题,并将其标记为已回答。 这样,可能有类似问题的其他人会看到你的答案。