ディレクトリツリーハウスを表示するプログラムを書く


9

C:/stdinから、またはファイルから読み取られたディレクトリ(など)を指定すると、ディレクトリツリーが生成され、各ファイル/フォルダはその深さに基づいてインデントされます。

私が持っている場合C:/のみ、2つのフォルダーを含むドライブをfooしてbar、そしてbar空のときにfoo含まれているbaz.txt場合、入力して実行すると、C:/生成します。

C:/
    bar/
    foo/
        baz.txt

入力で実行している間C:/foo/

foo/
    baz.txt

これはコードゴルフなので、バイト数が最も少ないものが優先されます。ファイル拡張子(などbaz.txt)はオプションです。補足:隠しファイルは無視できます。ディレクトリは実際に存在している必要があります。ファイルには印刷できない文字や改行は含まれていませんが、他のすべての印刷可能なASCII文字は問題ありません(スペースを含むファイル名をサポートする必要があります)。出力はファイルまたはstdoutに書き込むことができます。インデントは、タブ文字または4つのスペースで構成できます。


1
補足:この質問は形式が不十分なので、再フォーマットしていただければ幸いです。
Mathime

ファイルにアクセスできない言語は自動的に失格になりますか?
Leaky Nun

どのファイル名をサポートする必要がありますか?名前にスペースが含まれているファイル?改行付き?印刷できない文字を使って?(で始まる.)隠しファイルはどうですか?
ドアノブ

1
@LeakyNun参照質問の出力は配列の配列です。この質問では、標準出力に出力されるディレクトリツリーの表現が必要です。
Mathime

1
入力を関数への文字列パラメーターにすることはできますか?
mbomb007 2016

回答:


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
'

4バイトの@Dennisに感謝!


2

Dyalog APL、48 バイト

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

文字入力のプロンプト

'dir/s/b ', テキストを追加

⎕SH シェルで実行する

r←Rに保存

文字列のリストを文字行列にする

昇順ソートのインデックス

r[... ]再注文r [ソート済み]

(... )シェルコマンドの標準出力では、次のようにします。

'[^\\]+\\'⎕R' ' regexは、バックスラッシュで終了する非バックスラッシュの実行を4つのスペースに置き換えます

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この課題を読んだ後に-Libraryが発見した、通常はかなり機能的に使用されている言語StandardMLを使用しています。

特殊文字は!&$および%言語自体に特別な意味を持たず、単に識別子として使用されています。ただし、標準の英数字の識別子と混在させることはできません。これにより、他に必要なかなりのスペースを取り除くことができます。

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またはモスクワ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バイト

  • 最初の引数:パスには末尾にスラッシュ(またはバックスラッシュ)が必要です
  • 2番目の引数:レベルのデフォルトはで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)

グロブあり、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()ゴルフ$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
  • フラグ1RecursiveIteratorIterator::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はリテラルのタブ文字を表します。このバージョンには\、ディレクトリの末尾にsが含まれていますが、不要な場合は41バイトを保存できます。


末尾`\` sは必要とされていない
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]), "");
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.