微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ls如何sorting文件名?

我正在尝试编写一个函数来模仿Unix中ls命令的输出。 我最初尝试使用scandir和alphasort来执行此操作,而且确实打印了目录中的文件,并对它们进行了sorting,但由于某种原因,此sorting的列表似乎不匹配相同的“sorting列表”文件名那是给的。

例如,如果我有一个包含file.c,FILE.c和ls.c的目录。

ls按照以下顺序显示它们:file.c FILE.c ls.c但是当我使用alphasort / scandir对它进行sorting时,它将它们sorting为:FILE.c file.c ls.c

ls如何对目录中的文件进行sorting,使其得到如此不同的sorting结果?

在Linux脚本中是什么意思? #!/ usr / bin / python -tt

在Linux脚本中有条件地添加或附加到文件

为什么在Linux API和Bash中pipe道可以使用的进程之间的关系是不同的

如何获得pipe道中第一个命令的退出状态?

在Linux中将分隔文件转换为固定宽度

以root用户身份运行bash安装脚本 – 如何处理普通用户文件

不能在linux中创build僵尸进程

linux批量重命名目录和strip#字符从名字

如何检查一个程序是否在Windows上的Ubuntu上运行,而不仅仅是简单的Ubuntu?

删除目录及其子目录中的所有文件types

要模拟认的ls -1行为,请通过调用来使程序区域识别

setlocale(LC_ALL,"");

在main()的开头附近,并使用

count = scandir(dir,&array,my_filter,alphasort);

其中my_filter()是一个以点开头的名称返回0的函数. ,其他1个。 alphasort()一个使用语言环境排序顺序的POSIX函数,顺序与alphasort()相同。

基本的实现是沿着某些方向的

#define _POSIX_C_SOURCE 200809L #define _ATFILE_SOURCE #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <locale.h> #include <string.h> #include <dirent.h> #include <stdio.h> #include <errno.h> static void my_print(const char *name,const struct stat *info) { /* Todo: Better output; use info too,for 'ls -l' -style output? */ printf("%sn",name); } static int my_filter(const struct dirent *ent) { /* Skip entries that begin with '.' */ if (ent->d_name[0] == '.') return 0; /* Include all others */ return 1; } static int my_ls(const char *dir) { struct dirent **list = NULL; struct stat info; DIR *dirhandle; int size,i,fd; size = scandir(dir,&list,alphasort); if (size == -1) { const int cause = errno; /* Is dir not a directory,but a single entry perhaps? */ if (cause == ENOTDIR && lstat(dir,&info) == 0) { my_print(dir,&info); return 0; } /* Print out the original error and fail. */ fprintf(stderr,"%s: %s.n",dir,strerror(cause)); return -1; } /* We need the directory handle for fstatat(). */ dirhandle = opendir(dir); if (!dirhandle) { /* Print a warning,but continue. */ fprintf(stderr,"%s: %sn",strerror(errno)); fd = AT_FDCWD; } else { fd = dirfd(dirhandle); } for (i = 0; i < size; i++) { struct dirent *ent = list[i]; /* Try to get @R_348_4045@ion on ent. If fails,clear the structure. */ if (fstatat(fd,ent->d_name,&info,AT_SYMLINK_nofollow) == -1) { /* Print a warning about it. */ fprintf(stderr,strerror(errno)); memset(&info,sizeof info); } /* Describe 'ent'. */ my_print(ent->d_name,&info); } /* Release the directory handle. */ if (dirhandle) closedir(dirhandle); /* discard list. */ for (i = 0; i < size; i++) free(list[i]); free(list); return 0; } int main(int argc,char *argv[]) { int arg; setlocale(LC_ALL,""); if (argc > 1) { for (arg = 1; arg < argc; arg++) { if (my_ls(argv[arg])) { return EXIT_FAILURE; } } } else { if (my_ls(".")) { return EXIT_FAILURE; } } return EXIT_SUCCESS; }

请注意,我故意使这个复杂而不是严格按照你的目的需要,因为我不希望你复制和粘贴代码。 编译,运行和调查这个程序会比较容易,然后移植所需的更改 – 可能只是一个setlocale("",LC_ALL); 线! – 对你自己的程序,而不是试着向你的老师/讲师/助教解释为什么代码看起来像是从别处逐字复制的。

上面的代码甚至可以在命令行上指定的文件( cause == ENOTDIR部分)上工作。 它还使用单个函数my_print(const char *name,const struct stat *info)来打印每个目录条目; 要做到这一点,它确实为每个条目调用stat 。

my_ls()打开一个目录句柄,并使用fstatat(descriptor,name,struct stat *,AT_SYMLINK_nofollow)以与lstat()基本相同的方式收集信息,而不是构建目录条目的路径并调用lstat()会,但是name是一个相对路径开始于descriptor指定的目录( dirfd(handle) ,如果handle是一个开放的DIR * )。

确实为每个目录条目调用一个stat函数是“慢”(特别是如果你做/bin/ls -1样式的输出)。 然而, ls的产量是为了人类的消费量。 而且经常less地通过管道让人们休闲地观看它。 这就是为什么我个人不认为“额外”stat()调用(即使不是真的需要)在这里一个问题。 我所知道的大多数人类用户倾向于使用ls -l或(我最喜欢的) ls -laF --color=auto 。 ( auto含义只有在标准输出是终端时才使用ANSI颜色;即当isatty(fileno(stdout)) == 1 。

换句话说,现在你已经有了ls -1命令了,我建议你修改输出为类似于ls -l (破折号而不是破折号)。 你只需要修改my_print() 。

以字母数字(字典)顺序。

当然,这随语言而变化。 尝试:

$ LANG=C ls -1 FILE.c file.c ls.c

和:

$ LANG=en_US.utf8 ls -1 file.c FILE.c ls.c

这与“整理顺序”有关 。 不是任何一个简单的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐