编写程序以显示目录树屋


9

C:/从stdin或从文件读取的给定目录(例如)产生目录树,每个文件/文件夹根据其深度缩进。

如果我有一个C:/驱动器只包含两个文件夹foobar,和bar是空的,而foo含有baz.txt,那么在运行的输入C:/产生:

C:/
    bar/
    foo/
        baz.txt

输入运行时会C:/foo/产生

foo/
    baz.txt

因为这是codegolf,所以最低字节数为准。文件扩展名(例如baz.txt)是可选的。附加说明:隐藏的文件可以忽略,目录必须实际存在,可以假定文件不包含不可打印的字符或换行符,但所有其他可打印的ASCII字符都很好(必须支持带空格的文件名)。可以将输出写入文件或标准输出。缩进可以由制表符或4个空格组成。


1
特别说明:这个问题的格式不正确,因此请重新格式化。
Mathime '16

无法访问文件的语言会自动取消资格吗?
Leaky Nun

必须支持哪些文件名?名称中带有空格的文件?有换行符吗?带有无法打印的字符?隐藏的文件(以开头.)呢?
Doorknob

1
@LeakyNun参考问题的输出是一个数组数组。这个问题需要将目录树的表示形式打印到stdout。
Mathime '16

1
输入可以是函数的字符串参数吗?
mbomb007 '16

Answers:


10

bash,61 58 54字节

find "$1" -exec ls -Fd {} \;|perl -pe's|.*?/(?!$)|  |g'

将输入作为命令行参数,在STDOUT上输出。

请注意,末尾附近的空格|g实际上是制表符(SE在显示帖子时将其转换为空格)。

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
'

感谢@Dennis提供4个字节!


2

Dyalog APL,48 个字节

(⊂∘⊃,1↓'[^\\]+\\'⎕R'    ')r[⍋↑r←⎕SH'dir/s/b ',⍞]

提示输入字符

'dir/s/b ', 前置文字

⎕SH 在shell中执行

r←存放在r

将字符串列表转换为字符矩阵

升序索引

r[... ]重新排序r [排序]

(... )按照标准的shell命令执行:

'[^\\]+\\'⎕R' ' 正则表达式将反斜杠终止的非反斜杠运行替换四个空格

1↓ 删除第一行

⊂∘⊃, 在附上的第一行之前

在提示符下输入“ \ tmp”的结果在我的计算机上开始如下:

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


目录不应该带有尾随\字符吗?
尼尔


2

SML,176字节

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)

声明(以及其他)函数%,该函数将字符串作为参数。用% "C:/Some/Path";或调用% (getDir());当前目录。

我使用的是标准功能上FileSys较为常用的语言StandardML,在阅读了该挑战后发现了-Library。

特殊字符!&$%在语言本身没有特殊的含义,只是用作标识符; 但是,它们不能与标准字母数字标识符混合使用,从而可以消除很多其他需要的空格。

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 &
)

可以使用SML / NJ或Moscow ML * 像这样编译,只需添加前缀即可load"OS";

*请参阅mosml.org,最多只能发布2个链接。


1

C#(.NET Core),222字节

namespace System.IO{class P{static int n;static void Main(String[]a){Console.WriteLine(new string('\t',n++)+Path.GetFileName(a[0]));try{foreach(var f in Directory.GetFileSystemEntries(a[0])){a[0]=f;Main(a);}}catch{}n--;}}}

在线尝试!


高尔夫:

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("\t");
        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--;
    }
}

我第一次递归一个Main函数!

我相信对C#有较新知​​识的人可以打高尔夫,因为我有一段时间没有使用C#了!


0

PHP,180字节

  • 第一个参数:路径必须带有斜杠(或反斜杠)
  • 第二个参数:电平默认为NULL与将被解释为0通过str_repeat; 如果未提供,将发出警告

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
";}
  • 显示隐藏的文件和目录,但没有递归隐藏目录
    周围添加括号is_dir(...)?d(...):"..."从输出(2)除去隐藏的条目
    替换"#^\.#"#^\.+$#到显示/隐藏递归条目但跳过点条目(2)
  • 目录嵌套太深时可能会引发错误。closedir($s);在决赛前插入}以解决(+13)
  • 如果目录中包含没有名称的条目,将失败,false!==并以while条件修复(+8)

与glob,182个字节(将来的php中可能为163 个字节

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)."
";}
  • 不显示或递归隐藏的文件/目录
  • 2代表GLOB_MARK,将在所有目录名称后加上斜杠,ls -F
  • 我可能为此滥用的preg_replace转义字符(-19);但这在Windows系统上将失败,因为反斜杠是目录分隔符。
    preg_quote
  • php 可能很快会包含一个功能glob_quote,它将允许与preg_quote所有系统相同的打法并在所有系统上工作。

带有183个字节的迭代器
(嗯,不是纯粹的迭代器:我将隐式SplFileInfo::__toString()用于golf $f->getBaseName()$f->isDir()旧的PHP 4函数。)

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)?"/":"","
";}
  • 不需要尾部斜杠
  • 显示和递归隐藏的条目(ls -a
  • 插入,4096,FilesystemIterator::SKIP_DOTS之前),1跳过点输入(+5)(ls -A
  • 标志1代表RecursiveIteratorIterator::SELF_FIRST

0

PowerShell,147个字节

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

伙计,我觉得PS应该可以执行bash答案之类的事情,但我没有提出比我在这里短的东西。

说明:

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

0

Python 2,138字节

这个SO答案修改。这些是缩进的选项卡,而不是空格。输入将采用"C:/"

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

在线尝试 -非常有趣的是,我可以浏览Ideone上的目录...

相同长度:

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

0

批次,237个字节

@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%

其中\ t代表文字制表符。此版本包含\目录中的尾随,但如果不需要则可以保存41个字节。


不需要尾随的\
仅ASCII码

0

Perl,89个字节

当核心发行版中有一个find模块时,这很有用。Perl的File :: Find模块不会按字母顺序遍历树,但是规范并没有要求。

/usr/bin/perl -MFile::Find -nE 'chop;find{postprocess,sub{--$d},wanted,sub{say" "x$d.$_,-d$_&&++$d&&"/"}},$_'

正确的脚本是76个字节,我为命令行选项算了13个字节。



0

Java 8,205字节

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]),"");}}

这是完整的程序提交,它从其第一个命令行参数(未明确允许,但由许多其他参数完成)中获取输入,并将输出打印到标准输出中。

在线尝试(注意不同的接口名称)

不打高尔夫球

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]), "");
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.