如何使用通配符“*”实现命令'ls'?

时间:2013-04-15 12:50:51

标签: unix system-calls

编辑#1:我的限制是所有参数都用两个引号括起来,所以shell不会将*的任何参数扩展到相应的路径。

编辑#2:为了检索诸如*/*../*dirA/*/file.out之类的目录,我应该如何使用迭代循环或递归调用?

我刚刚了解了函数fnmatch()。但我不知道开始的地方 有很多可能的情况。我很困惑处理这些案件。
例如,我假设可执行程序是a.out

$./a.out -l */*
$./a.out -l ../*
$./a.out -l [file_name] [directory_name] 
/* Since I also have to implement ls command with no wildcard. */

我该怎么办?任何建议都很棒 提前谢谢。

2 个答案:

答案 0 :(得分:0)

你的问题是:shell用所有匹配模式的文件名替换了通配符caracter *。

解决方案:

如果您不想使用bash的这个功能,只需在命令行参数周围加上引号。

以这种方式调用程序将包含原始参数,包含通配符。

在此之后,您可以列出所有文件名及其路径。例如,使用一些递归算法。然后,您可以对这些路径字符串应用一些匹配。 (访问时)

答案 1 :(得分:0)

如果你想成为一个优秀的unix公民,规则是除非你正在写一个shell,否则不要做文件名通配。

你想写一个类似ls的程序吗?不要做任何通配符扩展。不要特别对待“*”。只需将argv视为文件名列表即可。如果您的程序处理这些情况:

./a.out file1
./a.out file1 file2 file3

然后它也将处理

./a.out file*

正确,因为shell将进行扩展,您的程序将不需要知道它。除此之外,它将处理这个问题:

zsh% ./a.out **/file<40-185>~file<90-100>(.mm-30OL[1,2])

在zsh中扩展了glob语法意味着:将file40扩展到file185,除了file90到file100之外,只包括那些在过去30分钟内修改过的文件,并且只使用结果集中最大的2个文件。

fnmatch永远不会做那样的事情。但是这些花哨的glob可以用于任何只接受文件名列表的命令,而不关心它来自何处。

当您处于无法从命令行获取文件名列表的情况时,请考虑使用fnmatch。 ls不是其中之一。