C, 216 228 chars (#include included)
The other C solution contians nice tricks, but as I like compilable complete C solutions, here is my shot:
#include <dirent.h>
main(int _,char**v){char n[4096],*a=n,*b;DIR*d;struct dirent*e;(d=opendir(*++v))||puts(*v);while(d&&(e=readdir(d)))b=e->d_name,sprintf(n,"%s/%s",*v,b),strcmp(".",b)&&strcmp("..",b)&&main(0,&a-1);}
It's also a recursive traversal algorithm, and it's using the main
function as recursive function. The main function tries to open the path contained in argv[1]
. If it fails, it prints it, otherwise, it calls main on every sub-element (if it's different from "."
or ".."
).
Usage
It's a standalone, working C program:
$ gcc dir.c -o dir
$ ./dir /var.log
/var/log/kern.log.1
/var/log/alternatives.log.1
/var/log/user.log.2.gz
/var/log/nvidia-installer.log
/var/log/debug.4.gz
/var/log/wtmp.1
/var/log/lastlog
/var/log/messages.2.gz
/var/log/vmware-installer
/var/log/pm-powersave.log
/var/log/syslog.4.gz
/var/log/news/news.err
/var/log/news/news.notice
/var/log/news/news.crit
/var/log/apt/history.log.3.gz
/var/log/apt/history.log.9.gz
/var/log/apt/history.log.4.gz
/var/log/apt/term.log.10.gz
/var/log/apt/history.log.10.gz
/var/log/apt/term.log.4.gz
Tips
I used a few (somewhat classic) C tricks:
- replace
if(condition)statement
with contition && statement
- replace
if(!condition)statement
with condition || statement
- use the
,
operator to save {
and }
in the while code
Here is a readable version:
#include <dirent.h>
main(int _,char**v) {
char n[4096], *a=n,*b;
DIR *d;
struct dirent *e;
(d = opendir(*++v)) || puts(*v);
while(d && (e = readdir(d)))
b = e->d_name,
sprintf(n, "%s/%s", *v, b),
strcmp(".", b)&&strcmp("..", b)&&
main(0, &a-1);
}
Edit
I have to insert a closedir(d);
statement at the end, because a limit is reached when too much folders are opened (wild guess: the open files limit) and the the program stops. This happens only for folder containing many other folders.
the code is now:
#include <dirent.h>
main(int _,char**v){char n[4096],*a=n,*b;DIR*d;struct dirent*e;(d=opendir(*++v))||puts(*v);while(d&&(e=readdir(d)))b=e->d_name,sprintf(n,"%s/%s",*v,b),strcmp(".",b)&&strcmp("..",b)&&main(0,&a-1);closedir(d);}
ls
(or, recursively,ls -R
)? \$\endgroup\$