| Bytes | Lang | Time | Link |
|---|---|---|---|
| 106 | Tcl | 170114T233138Z | sergiol |
| 221 | C# .NET Core | 170114T175659Z | sergiol |
| 132 | Python 2 | 160718T164722Z | mbomb007 |
| 205 | Java 8 | 180327T194755Z | Jakob |
| 089 | Perl | 170115T002249Z | user6440 |
| 237 | Batch | 160718T122726Z | Neil |
| 147 | PowerShell | 160718T161956Z | ThePoShW |
| 180 | PHP | 160718T134952Z | Titus |
| 176 | SML | 160717T233732Z | Laikoni |
| 048 | Dyalog APL | 160717T223132Z | Adá |
| 054 | bash | 160716T212233Z | Doorknob |
Tcl, 106 bytes
proc L {f n\ 0} {puts [string repe \t $n][file ta $f]
lmap c [glob -n -d $f *] {L $c [expr $n+1]}}
L $argv
C# (.NET Core), 221 bytes
namespace System.IO{class P{static int n;static void Main(String[]a){Console.WriteLine(new string(' ',n++)+Path.GetFileName(a[0]));try{foreach(var f in Directory.GetFileSystemEntries(a[0])){a[0]=f;Main(a);}}catch{}n--;}}}
The ungolf:
using System.IO;
using System;
class P
{
static int n=0;
static void Main(String[] a)
{
for (int i=0;i<n;i++) Console.Write(' ');
Console.WriteLine(Path.GetFileName(a[0]));
n++;
if(Directory.Exists(a[0]))
foreach (String f in Directory.GetFileSystemEntries(a[0]))
Main(new String[]{f});
n--;
}
}
First time I ever recursed a Main function!
I believe a person that has fresher knowledge of C# can golf it more, as I didn't program on C# for some time!
Python 2, 132 bytes
Modified from this SO answer. Those are tabs for indentation, not spaces. Input will be taken like "C:/" or /var.
import os
p=input()
for r,d,f in os.walk(p):
t=r.replace(p,'').count('/');print' '*t+os.path.basename(r)
for i in f:print' '*-~t+i
Try it online - It's pretty interesting that I'm allowed to browse the directory online...
from os import*
p=input()
for r,d,f in walk(p):
t=r.replace(p,'').count(sep);print' '*t+path.basename(r)
for i in f:print' '*-~t+i
Java 8, 205 bytes
import java.io.*;public interface M{static void p(File f,String p){System.out.println(p+f.getName());if(!f.isFile())for(File c:f.listFiles())p(c,p+"\t");}static void main(String[]a){p(new File(a[0]),"");}}
This is a full program submission which takes input from its first command-line argument (not explicitly permitted, but done by many others) and prints output to standard out.
Try It Online (note different interface name)
Ungolfed
import java.io.*;
public interface M {
static void p(File f, String p) {
System.out.println(p + f.getName());
if (!f.isFile())
for (File c : f.listFiles())
p(c, p + "\t");
}
static void main(String[] a) {
p(new File(a[0]), "");
}
}
Perl, 89 bytes
It's useful when there's a find module in the core distribution. Perl's File::Find module does not traverse the tree in alphabetic order, but the spec didn't ask for that.
/usr/bin/perl -MFile::Find -nE 'chop;find{postprocess,sub{--$d},wanted,sub{say" "x$d.$_,-d$_&&++$d&&"/"}},$_'
The script proper is 76 bytes, I counted 13 bytes for the command-line options.
Batch, 237 bytes
@echo off
echo %~1\
for /f %%d in ('dir/s/b %1')do call:f %1 %%~ad "%%d"
exit/b
:f
set f=%~3
call set f=%%f:~1=%%
set i=
:l
set i=\t%i%
set f=%f:*\=%
if not %f%==%f:*\=% goto l
set a=%2
if %a:~0,1%==d set f=%f%\
echo %i%%f%
Where \t represents the literal tab character. This version includes trailing \s on directories but 41 bytes can be saved if they are not needed.
PowerShell, 147 bytes
param($a)function z{param($n,$d)ls $n.fullname|%{$f=$_.mode[0]-ne"d";Write-Host(" "*$d*4)"$($_.name)$(("\")[$f])";If(!$f){z $_($d+1)}}}$a;z(gi $a)1
Man, I feel like PS should be able to do something like the bash answer, but I'm not coming up with anything shorter than what I've got here.
Explanation:
param($a) # assign first passed parameter to $a
function z{param($n,$d) ... } # declare function z with $n and $d as parameters
ls $n.fullname # list out contents of directory
|%{ ... } # foreach
$f=$_.namde[0]-ne"d" # if current item is a file, $f=true
Write-Host # writes output to the console
(" "*$d*4) # multiplies a space by the depth ($d) and 4
"$($_.name)$(("\")[$f])" # item name + the trailing slash if it is a directory
;if(!$f){z $_($d+1)} # if it is a directory, recursively call z
$a # write first directory to console
z(gi $a)1 # call z with $a as a directoryinfo object and 1 as the starting depth
PHP, 180 bytes
- first argument: path must have a trailing slash (or backslash)
- second argument: level defaults to
NULLand will be interpreted as0bystr_repeat; will throw a warning if not provided
function d($p,$e){$s=opendir($p);echo$b=str_repeat("\t",$e++),$e?basename($p)."/":$p,"
";while($f=readdir($s))echo preg_match("#^\.#",$f)?"":is_dir($p.$f)?d("$p$f/",$e):"$b\t$f
";}
- displays hidden files and directories, but does not recurse hidden directories
add parentheses aroundis_dir(...)?d(...):"..."to remove hidden entries from output (+2)
replace"#^\.#"with#^\.+$#to display/recurse hidden entries but skip dot entries (+2) - may throw errors when directories are nested too deep. Insert
closedir($s);before the final}to fix (+13) - will fail if a directory contains an entry with no name, prepend
false!==to the while condition to fix (+8)
with glob, 182 bytes (probably 163 in future php)
function g($p,$e){echo$b=str_repeat("\t",$e),$e++?basename($p)."/":$p,"
";foreach(glob(preg_replace("#[*?[]#","[$1]",$p)."*",2)as$f)echo is_dir($f)?g($f,$e):"$b\t".basename($f)."
";}
- does not display or recurse hidden files/directories
2stands forGLOB_MARK, will append a slash to all directory names, as doesls -F- the
preg_replaceescapes glob special characters
I could have abusedpreg_quotefor this (-19); but that would fail on Windows systems, as the backslash is the directory separator there. - php may soon include a function glob_quote, which will allow the same golfing as
preg_quoteand work on all systems.
with iterators, 183 bytes
(well, not purely iterators: I used implicit SplFileInfo::__toString() to golf $f->getBaseName() and $f->isDir() to the old PHP 4 functions.)
function i($p){echo"$p
";foreach($i=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($p),1)as$f)echo str_repeat("\t",1+$i->getDepth()),basename($f),is_dir($f)?"/":"","
";}
- no trailing slash required
- displays and recurses hidden entries (
ls -a) - insert
,4096or,FilesystemIterator::SKIP_DOTSbefore),1to skip dot entries (+5) (ls -A) - flag
1stands forRecursiveIteratorIterator::SELF_FIRST
SML, 176 bytes
open OS.FileSys;val! =chDir;fun&n w=(print("\n"^w^n);!n;print"/";c(openDir(getDir()))(w^"\t");!"..")and c$w=case readDir$of SOME i=>(&i w handle _=>();c$w)|x=>()fun%p=(&p"";!p)
Declares (amongst others) a function % which takes a string as argument. Call with % "C:/Some/Path"; or % (getDir()); for the current directory.
I'm using the normally rather functionally used language StandardML whose FileSys-Library I discovered after reading this challenge.
The special characters !, &, $ and % have no special meaning in the language itself and are simply used as identifiers; however they can't be mixed with the standard alphanumeric identifiers which allows to get rid of quite some otherwise needed spaces.
open OS.FileSys;
val ! = chDir; define ! as short cut for chDir
fun & n w = ( & is the function name
n is the current file or directory name
w is a string containing the tabs
print ("\n"^w^n); ^ concatenates strings
! n; change in the directory, this throws an
exception if n is a file name
print "/"; if we are here, n is a directory so print a /
c (openDir(getDir())) (w^"\t"); call c with new directory and add a tab to w
to print the contents of the directory n
! ".." we're finished with n so go up again
)
and c $ w = 'and' instead of 'fun' must be used
because '&' and 'c' are mutual recursive
$ is a stream of the directory content
case readDir $ of case distinction whether any files are left
SOME i => ( yes, i is the file or directory name
& i w handle _ => (); call & to print i an check whether it's a
directory or not, handle the thrown exception
c $ w ) recursively call c to check for more files in $
| x => () no more files, we are finished
fun % p = ( % is the function name,
p is a string containing the path
& p ""; call & to print the directory specified by p
and recursively it's sub-directories
! p change back to path p due to the ! ".." in &
)
Can be compiled like this with SML/NJ or with Moscow ML* by prefixing with load"OS";.
*See mosml.org, can't post more than 2 links.
Dyalog APL, 48 bytes
(⊂∘⊃,1↓'[^\\]+\\'⎕R' ')r[⍋↑r←⎕SH'dir/s/b ',⍞]
⍞ prompt for character input
'dir/s/b ', prepend text
⎕SH execute in shell
r← store in r
↑ make list of strings into character matrix
⍋ indices for ascending sorting
r[...] reorder r [sorted]
(...) on the standard out of the shell command, do:
'[^\\]+\\'⎕R' ' regex replace backslash-terminated runs of non-backslashes by four spaces
1↓ drop the first line
⊂∘⊃, prepend the enclosed first [line]
Result of inputting "\tmp" to the prompt begins as follows on my computer:
C:\tmp\12u64
keyboards64.msi
netfx64.exe
setup.exe
setup_64_unicode.msi
setup_dotnet_64.msi
AdamsReg.reg
AdamsReg.zip
qa.dws
ride-experimental
win32
d3dcompiler_47.dll
icudtl.dat
libEGL.dll
⋮
bash, 61 58 54 bytes
find "$1" -exec ls -Fd {} \;|perl -pe's|.*?/(?!$)| |g'
Takes input as a command line argument, outputs on STDOUT.
Note that the spaces near the end before the |g are actually a tab character (SE converts them to spaces when displaying posts).
find crawl directory tree recursively
"$1" starting at the input directory
-exec and for each file found, execute...
ls -Fd {} \; append a trailing slash if it's a directory (using -F of ls)
|perl -pe pipe each line to perl
'
s| replace...
.*?/ each parent directory in the file's path...
(?!$) that doesn't occur at the end of the string...
| | with a tab character...
g globally
'
Thanks to @Dennis for 4 bytes!