Unix/ls

From Rosetta Code
Task
Unix/ls
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Write a program that will list everything in the current folder,   similar to:

  •   the Unix utility   “ls”   [1]       or
  •   the Windows terminal command   “DIR


The output must be sorted, but printing extended details and producing multi-column output is not required.


Example output

For the list of paths:

/foo/bar
/foo/bar/1
/foo/bar/2
/foo/bar/a
/foo/bar/b


When the program is executed in   `/foo`,   it should print:

bar

and when the program is executed in   `/foo/bar`,   it should print:

1
2
a
b



11l

Translation of: Python
print(sorted(fs:list_dir(‘.’)).join("\n"))

8080 Assembly

This program runs under CP/M and lists the current directory. CP/M does not return the filenames in sorted order, so it has to do the sorting itself.

dma:		equ	80h
puts:		equ	9h		; Write string to console
sfirst:		equ	11h		; Find first matching file
snext:		equ	12h		; Get next matching file
		org	100h
		;;;	First, retrieve all filenames in current directory
		;;;	CP/M has function 11h (sfirst) and function 13h (snext)
		;;;	to return the first, and then following, files that
		;;;	match a wildcard.
		lxi	d,0		; Amount of files
		push	d 		; Push on stack 
		lxi	h,fnames	; Start of area to save names 
		push	h 		; Push on stack
		lxi	d,fcb		; FCB that will match any file
		mvi	c,sfirst	; Get the first file
getnames:	call	5		; Call CP/M BDOS
		inr	a		
		jz	namesdone	; FF = we have all files
		dcr	a		; Dir entry is at DMA+32*A	
		rrc			; Rotate 3 right, same as
		rrc			; rotate 5 left, *32
		rrc
		adi	dma+1		; Add DMA offset + 1 (filename offset)
		mov	e,a		; Low byte of address
		mvi	d,0		; High byte is 0
		mvi	b,8		; Filename is 8 bytes
		pop	h		; Get pointer to name area
		call	memcpy		; Copy the name
		mvi	m,' '		; Separate name and extension
		inx	h
		mvi	b,3		; Extension is 3 bytes
		call 	memcpy		; Copy the extension
		mvi	m,13		; While we're at it, terminate
		inx	h		; the filename with \r\n
		mvi 	m,10
		inx	h
		pop	d		; Get amount of files
		inx	d		; Increment it (we've added a file)
		push 	d 		; Put it back onto the stack
		push	h		; Put the name pointer on the stack too
		mvi	c,snext		; Go get the next file
		jmp	getnames
namesdone:	pop	h		; Terminate the file list with $
		mvi	m,'$'		; so it can be printed with function 9
		;;;	CP/M does not keep its directory in sorted order,
		;;;	so we need to sort the list of files ourselves.
		;;;	What follows is a simple insertion sort.
		lxi	d,1		; DE (i) = 1
sortouter:	pop	h		; Get amount of files
		push	h 
		call 	cmpdehl		; i < length(files)?
		jnc	sortdone	; If not, we're done
		push	d		; push i; DE (j) = i
sortinner:	push	d		; push j	
		mov	a,d		; j > 0?
		ora	e
		jz	sortinnerdone	; If not, inner loop is done
		dcx	d		; DE = j-1
		call	lookup		; HL = files[j-1]
		push	h		; push files[j-1]
		inx	d		; DE = j
		call 	lookup		; HL = files[j]
		pop	d		; pop DE = files[j-1]
		push	d		; keep them across comparison
		push	h
		call 	cmpentries	; A[j] >= A[j-1]?
		pop	h
		pop	d
		jc	sortinnerdone	; Then inner loop is done.
		mvi	b,12		; Otherwise we should swap them
swaploop:	ldax	d		; Get byte from files[j-1]
		mov	c,m		; Get byte from files[j]
		mov	m,a		; files[j][x]=files[j-1][x]
		mov	a,c		; files[j-1][x]=files[j]-[x]
		stax	d
		inx	h		; Increment pointers
		inx	d
		dcr	b		; all 12 bytes done yet?
		jnz	swaploop	; if not, swap next byte
		pop	d		; DE = j
		dcx	d		; j = j-1
		jmp	sortinner
sortinnerdone:	pop	d		; pop j
		pop	d		; pop i
		inx	d		; i = i + 1
		jmp	sortouter
sortdone:	pop	h		; Remove file count from stack 	
		;;;	We're done sorting the list, print it. 
		lxi	d,fnames	; Print the now sorted list of files
		mvi	c,puts
		jmp	5
		;;;	Subroutine: compare entries under DE and HL
cmpentries:	mvi	b,12		; Each entry has 12 relevant bytes.
cmploop:	ldax	d		; Get byte from entry DE
		cmp	m 		; Compare with byte from entry HL
		rnz			; If they differ, we know the ordering
		inx	h		; Increment both pointers
		inx	d
		dcr	b 		; Decrement byte counter
		jnz	cmploop		; Compare next byte
		ret
		;;;	Subroutine: look up filename entry (HL=DE*14+fnames)
lookup:		push	d		; Save entry number
		mov	h,d
		mov	l,e
		dad	h		; HL = HL' * 2
		dad	d		; HL = HL' * 3
		dad	h		; HL = HL' * 6
		dad	d		; HL = HL' * 7
		dad	h		; HL = HL' * 14
		lxi	d,fnames	; Offset
		dad	d 		; Add the offset
		pop	d 		; Restore entry number
		ret
		;;;	Subroutine: compare DE and HL
cmpdehl:	mov	a,d
		cmp	h
		rnz
		mov	a,e
		cmp	l
		ret
		;;;	Subroutine: copy B bytes from DE to HL
memcpy:		ldax	d		; Get byte from source
		mov	m,a		; Store byte at destination
		inx	h		; Increment both pointers
		inx	d
		dcr	b		; Done yet?
		jnz	memcpy		; If not, copy next byte
		ret 
		;;;	File control block used to specify wildcard
fcb:		db	0,'???????????'	; Accept any file
		ds	fcb+36-$	; Pad the FCB out to 36 bytes 
fnames:

8th

"*" f:glob 
' s:cmp a:sort
"\n" a:join .

Ada

with Ada.Text_IO, Ada.Directories, Ada.Containers.Indefinite_Vectors; 

procedure Directory_List is
   
   use Ada.Directories, Ada.Text_IO;
   Search: Search_Type; Found: Directory_Entry_Type;
   package SV is new Ada.Containers.Indefinite_Vectors(Natural, String);
   Result: SV.Vector;
   package Sorting is new SV.Generic_Sorting; use Sorting;
   function SName return String is (Simple_Name(Found));
   
begin
   -- search directory and store it in Result, a vector of strings
   Start_Search(Search, Directory => ".", Pattern =>"");
   while More_Entries(Search) loop
      Get_Next_Entry(Search, Found);
      declare
         Name: String := Simple_Name(Found);
      begin
         if Name(Name'First) /= '.' then
            Result.Append(Name);
         end if; -- ingnore filenames beginning with "."
      end;
   end loop; -- Result holds the entire directory in arbitrary order
   
   Sort(Result); -- Result holds the directory in proper order

   -- print Result
   for I in Result.First_Index .. Result.Last_Index loop 
      Put_Line(Result.Element(I));
   end loop;   
end Directory_List;

Aime

record r;
file f;
text s;

f.opendir(1.argv);

while (~f.case(s)) {
    if (s != "." && s != "..") {
        r[s] = 0;
    }
}

r.vcall(o_, 0, "\n");

Arturo

print list "."

AWK

Works with: gawk

"BEGINFILE" is a gawk-extension

# syntax: GAWK -f UNIX_LS.AWK * | SORT
BEGINFILE {
    printf("%s\n",FILENAME)
    nextfile
}
END {
    exit(0)
}

Sample commands and output under Windows 8:

REM create folders and files
MKDIR c:\foo\bar
CD /D c:\foo\bar
GAWK "BEGIN{x=\"12ab\";for(i=1;i<=length(x);i++){print(i)>substr(x,i,1)}}"
REM run test
CD /D c:\foo
GAWK -f UNIX_LS.AWK * | SORT
bar
CD /D c:\foo\bar
GAWK -f UNIX_LS.AWK * | SORT
1
2
a
b
Works with: gawk

To replicate 'ls .'

gawk -lreaddir 'BEGIN { FS = "/" } {print $2}' .
Works with: gawk

To replicate 'ls examplefile.txt'

gawk -lfilefuncs -lreaddir 'BEGIN { FS = "/"; stat(ARGV[1], fd); if(fd["type"] == "file") {print ARGV[1]; exit} } { print $2}' examplefile.txt

BaCon

' Emulate ls
cnt% = 0
files$ = ""
OPEN CURDIR$ FOR DIRECTORY AS mydir
GETFILE myfile$ FROM mydir
WHILE ISTRUE(LEN(myfile$))
    IF LEFT$(myfile$, 1) != "." THEN
        INCR cnt%
        files$ = APPEND$(files$, cnt%, UNFLATTEN$(myfile$))
    ENDIF
    GETFILE myfile$ FROM mydir
WEND
CLOSE DIRECTORY mydir
IF cnt% > 0 THEN
    FOR f$ IN SORT$(files$)
        PRINT FLATTEN$(f$)
    NEXT
ENDIF


BASIC256

directory$ = dir("m:\foo\bar\")	#Specified directory 
#directory$ = dir(currentdir)	#Current directory

while directory$ <> ""
	print directory$
	directory$ = dir()
end while
end


C

C does not have any os-independent way of reading a directory. The following uses readdir and should work on any Unix system.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

int cmpstr(const void *a, const void *b)
{
    return strcmp(*(const char**)a, *(const char**)b);
}

int main(void)
{
    DIR *basedir;
    char path[PATH_MAX];
    struct dirent *entry;
    char **dirnames;
    int diralloc = 128;
    int dirsize  = 0;
    
    if (!(dirnames = malloc(diralloc * sizeof(char*)))) {
        perror("malloc error:");
        return 1;
    }

    if (!getcwd(path, PATH_MAX)) {
        perror("getcwd error:");
        return 1;
    }

    if (!(basedir = opendir(path))) {
        perror("opendir error:");
        return 1;
    }

    while ((entry = readdir(basedir))) {
        if (dirsize >= diralloc) {
            diralloc *= 2;
            if (!(dirnames = realloc(dirnames, diralloc * sizeof(char*)))) {
                perror("realloc error:");
                return 1;
            }
        }
        dirnames[dirsize++] = strdup(entry->d_name);
    }

    qsort(dirnames, dirsize, sizeof(char*), cmpstr);

    int i;
    for (i = 0; i < dirsize; ++i) {
        if (dirnames[i][0] != '.') {
            printf("%s\n", dirnames[i]);
        }
    }

    for (i = 0; i < dirsize; ++i)
        free(dirnames[i]);
    free(dirnames);
    closedir(basedir);
    return 0;
}

C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Unix_ls
{
    public class UnixLS
    {
        public static void Main(string[] args)
        {
            UnixLS ls = new UnixLS();
            ls.list(args.Length.Equals(0) ? "." : args[0]);
        }

        private void list(string folder)
        {
            foreach (FileSystemInfo fileSystemInfo in new DirectoryInfo(folder).EnumerateFileSystemInfos("*", SearchOption.TopDirectoryOnly))
            {
                Console.WriteLine(fileSystemInfo.Name);
            }
        }
    }
}

C++

Library: Boost
#include <iostream>
#include <set>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

int main(void)
{
    fs::path p(fs::current_path());
    std::set<std::string> tree;

    for (auto it = fs::directory_iterator(p); it != fs::directory_iterator(); ++it)
        tree.insert(it->path().filename().native());

    for (auto entry : tree)
        std::cout << entry << '\n';
}

Clojure

(def files (sort (filter #(= "." (.getParent %)) (file-seq (clojure.java.io/file ".")))))

(doseq [n files] (println (.getName n)))

Common Lisp

In some implementations, `(directory)` results automatically include subdirectories (e.g. SBCL); some require them to be requested separately (e.g. CLISP). The function below asks for both and then removes any duplicates from the resulting list.

The workhorse is `files-list`, which returns a list of filenames. The `ls` function sorts the resulting list and formats it for output.

(defun files-list (&optional (path "."))
  (let* ((dir (concatenate 'string path "/"))
         (abs-path (car (directory dir)))
         (file-pattern (concatenate 'string dir "*"))
         (subdir-pattern (concatenate 'string file-pattern "/")))
    (remove-duplicates
       (mapcar (lambda (p) (enough-namestring p abs-path))
               (mapcan #'directory (list file-pattern subdir-pattern)))
       :test #'string-equal)))

(defun ls (&optional (path "."))
  (format t "~{~a~%~}" (sort (files-list path) #'string-lessp)))

D

void main() {
    import std.stdio, std.file, std.path, std.array, std.algorithm;

    foreach (const string path; dirEntries(getcwd, SpanMode.shallow).array.sort)
        path.baseName.writeln;
}

Delphi

program LsCommand;

{$APPTYPE CONSOLE}



uses
  System.SysUtils,
  System.IoUtils;

procedure Ls(folder: string = '.');
var
  offset: Integer;
  fileName: string;

  // simulate unix results in windows

  function ToUnix(path: string): string;
  begin
    Result := path.Replace('/', PathDelim, [rfReplaceAll])
  end;

begin
  folder := IncludeTrailingPathDelimiter(ToUnix(folder));
  offset := length(folder);

  for fileName in TDirectory.GetFileSystemEntries(folder, '*') do
    writeln(^I, ToUnix(fileName).Substring(offset));
end;

begin
  writeln('cd foo'#10'ls');
  ls('foo');

  writeln(#10'cd bar'#10'ls');
  ls('foo/bar');

  {$IFNDEF LINUX} readln; {$ENDIF}
end.
Output:
cd foo
ls
        bar

cd bar
ls
        1
        2
        a
        b

EchoLisp

No directory in EchoLisp, which is run in a browser window. Instead, "stores" (folders) and keys in stores (file names) are located in local storage.

;; ls of stores (kind of folders)
(for-each writeln (list-sort < (local-stores)))  
    AGES    
    NEMESIS    
    info    
    objects.dat    
    reader    
    system    
    user    
    words    

;; ls of "NEMESIS" store
(for-each writeln (local-keys "NEMESIS"))  
    Alan    
    Glory    
    Jonah

Elixir

iex(1)> ls = fn dir -> File.ls!(dir) |> Enum.each(&IO.puts &1) end
#Function<6.54118792/1 in :erl_eval.expr/5>
iex(2)> ls.("foo")
bar
:ok
iex(3)> ls.("foo/bar")
1
2
a
b
:ok

Erlang

1> Ls = fun(Dir) ->
1> {ok, DirContents} = file:list_dir(Dir),
1> [io:format("~s~n", [X]) || X <- lists:sort(DirContents)]
1> end.
#Fun<erl_eval.6.36634728>
2> Ls("foo").
bar
[ok]
3> Ls("foo/bar").
1
2
a
b
[ok,ok,ok,ok]

F#

Works with .NET framework 4.

let ls = DirectoryInfo(".").EnumerateFileSystemInfos() |> Seq.map (fun i -> i.Name) |> Seq.sort |> Seq.iter (printfn "%s")

Prior to .NET4 you had to enumerate files and directories separately.

The call to sort is probably redundant, since "sorted by name" seems to be the default in Windows.

Forth

This is much easier without the 'sorted output' requirement:

256 buffer: filename-buf
: each-filename { xt -- }  \ xt-consuming variant
  s" ." open-dir throw { d }
  begin filename-buf 256 d read-dir throw while
    filename-buf swap xt execute
  repeat  d close-dir throw ;

\ immediate variant
: each-filename[  s" ." postpone sliteral ]] open-dir throw >r begin filename-buf 256 r@ read-dir throw while filename-buf swap [[ ; immediate compile-only
: ]each-filename  ]] repeat drop r> close-dir throw [[ ; immediate compile-only

: ls ( -- )  [: cr type ;] each-filename ;

Given that requirement, we must first generate a sorted array of filenames:

: save-string ( c-addr u -- a )
  dup 1+ allocate throw dup >r place r> ;

require ffl/car.fs
: sorted-filenames ( -- car )
  0 car-new { a }
  [: swap count rot count compare ;] a car-compare!
  each-filename[ save-string a car-insert-sorted ]each-filename
  a ;

: each-sorted-filename ( xt -- )
  sorted-filenames { a }  a car-execute  [: free throw ;] a car-execute  a car-free ;

: ls ( -- )
  [: count cr type ;] each-sorted-filename ;

Fortran

This is possible only for those Fortran compilers that offer some sort of interface with the operating system's file handling routines. Not standard at all!

      PROGRAM LS		!Names the files in the current directory.
      USE DFLIB			!Mysterious library.
      TYPE(FILE$INFO) INFO	!With mysterious content.
      NAMELIST /HIC/INFO	!This enables annotated output.
      INTEGER MARK,L		!Assistants.

      MARK = FILE$FIRST		!Starting state.
Call for the next file.
   10 L = GETFILEINFOQQ("*",INFO,MARK)	!Mystery routine returns the length of the file name.
      IF (MARK.EQ.FILE$ERROR) THEN	!Or possibly, not.
        WRITE (6,*) "Error!",L		!Something went wrong.
        WRITE (6,HIC)			!Reveal INFO, annotated.
        STOP "That wasn't nice."	!Quite.
      ELSE IF (IAND(INFO.PERMIT,FILE$DIR) .EQ. 0) THEN	!Not a directory.
        IF (L.GT.0) WRITE (6,*) INFO.NAME(1:L)	!The object of the exercise!
      END IF				!So much for that entry.
      IF (MARK.NE.FILE$LAST) GO TO 10	!Lastness is discovered after the last file is fingered.
      END	!If FILE$LAST is not reached, "system resources may be lost."

This relies on the supplied routine GETFILEINFOQQ, which is not at all a standard routine, but it does behave in the same way as is found in many other systems, notably with a file name selection filter, here chosen to be "*" meaning "any file". It supplies successive file names and requires mysterious parameters to keep track of what it is doing. In the installation file C:/Compilers/Furrytran/Compaq Furrytran 6.6a CD/X86/DF/INCLUDE/DFLIB.F90, there is the following segment:

      INTERFACE
	INTEGER*4 FUNCTION GETFILEINFOQQ(FILES, BUFFER,dwHANDLE)
!DEC$ ATTRIBUTES DEFAULT :: GETFILEINFOQQ
	  CHARACTER*(*) FILES
	  STRUCTURE / FILE$INFO /
	    INTEGER*4       CREATION          ! Creation time (-1 on FAT)
	    INTEGER*4       LASTWRITE         ! Last write to file
	    INTEGER*4       LASTACCESS        ! Last access (-1 on FAT)
	    INTEGER*4       LENGTH            ! Length of file
	    INTEGER*2       PERMIT            ! File access mode
	    CHARACTER*255   NAME              ! File name
	  END STRUCTURE
	  RECORD / FILE$INFO / BUFFER
	  INTEGER*4 dwHANDLE
	END FUNCTION
      END INTERFACE

Getting this to work was quite annoying. It turned out that the irritating "files" . and .. are deemed a directory (via the bit in INFO.PERMIT matching that of FILE$DIR = 16) and so can be skipped along with proper subdirectories, but the "PERMIT" value of -1 returned for the FILE$LAST state also matches, though its (non-existent) file name length is given as zero. Thus, if one skips directories filter-style by IF ... GO TO 10, in such a case the end will never be seen. Further, although Fortran syntax allows INFO.PERMIT .AND. FILE$DIR the bit values of logical variables are strange. Instead, what is needed is IAND(INFO.PERMIT,FILE$DIR)

Further vexation was due to the compiler's "help" system giving PERMIT as a 32-bit integer in its example. Copying the declaration to give a type name not involving a dollar symbol foundered because the type checking done by the compiler for the parameters of the function is based not on the contents of the type matching, but on the name of the type matching. So, one is stuck with the $. In a mood for retaliation, some special tests were made, involving a pause for input after each name was revealed. Removing the file just named before responding to the request for input did not prevent the next file from being named, nor (in another run) did removing the file next to be named: although it was gone, it was still named in the next step as if it were still there, and this worked even if INFO.NAME were scrubbed each time as well. Evidently, there could arise transient problems when using this scheme in a file system undergoing turbulence.

As for the ordering of results, on this Windows XP system, the file names came out ordered so there is no need to mess about with a storage area to sort the names in.


FreeBASIC

#include "dir.bi"

Sub ls(Byref filespec As String, Byval attrib As Integer)   
    Dim As String filename = Dir(filespec, attrib)
    Do While Len(filename) > 0
        Print filename
        filename = Dir()
    Loop
End Sub

Dim As String directory = ""     ' Current directory
ls(directory & "*", fbDirectory)
Sleep

Frink

for f = sort[files["."], {|a,b| lexicalCompare[a.getName[], b.getName[]]}]
   println[f.getName[]]

FunL

import io.File

for f <- sort( list(File( "." ).list()).filterNot(s -> s.startsWith(".")) )
    println( f )
Output:

The above script has been placed in a file called ls.lf which has been placed in the home directory.

$ sudo mkdir -p /foo/bar
$ cd /foo/bar
$ sudo touch 1 2 a b
$ cd ..
$ funl ~/ls
bar
$ cd bar
$ funl ~/ls
1
2
a
b
$ 

Furor

The following program lists just the subdirectories, regular files and symlinks, because I do no need the other gizmos generally, but based on these abovementioned file types it is easy to expand with them, if it is necessary.

The output is indeed sorted, but not all filetypes alltogether: the sorting algorythm is invoked for the different filetypes separately, because it is the way I like it!

###sysinclude dir.uh
###sysinclude stringextra.uh

###define COLORS
// delete the COLORS directive above if you do not want colored output!
{ „vonal”  __usebigbossnamespace myself "-" 90 makestring() }
{ „points” __usebigbossnamespace myself "." 60 makestring() }
#g argc 3 < { "." }{ 2 argv } sto mypath
@mypath 'd !istrue { ."The give directory doesn't exist! Exited.\n" end }
@mypath getdir { ."Cannot load the dir! Aborted.\n" end } sto mydir

@mydir ~d {
."Directories:\n"
@mydir ~d  {| #s
@mydir 'd {} octalrights dup print free SPACE
@mydir 'd {} getfilename dup 37 stub print SPACE drop
@mydir 'd {} groupname ': !+
@mydir 'd {} ownername dup sto temp + dup 10 stub print free @temp free
@mydir 'd {} mtime dup print free
NL |}
@points sprint
@mydir ~d { ."Total: " @mydir ~d #g print ." subdirectories.\n" }
@vonal sprint
}
@mydir ~r {
."Regular files:\n"
@mydir ~r  {| #s
@mydir 'r {} octalrights dup print free SPACE
@mydir 'r {} getfilesize sbr §ifcolored
@mydir 'r {} executable { ." >" }{ ."  " } SPACE
@mydir 'r {} getfilename dup 37 stub print SPACE drop
@mydir 'r {} groupname ': !+
@mydir 'r {} ownername dup sto temp + dup 10 stub print free @temp free
@mydir 'r {} mtime dup print free
NL |}
@points sprint
@mydir ~r { ."Total: " @mydir ~r #g print ." regular files. "
."TotalSize = " @mydir 'r totalsize sbr §ifcolored NL
}
@vonal sprint
}
@mydir ~L {
."Symlinks:\n"
@mydir ~L  {| #s
@mydir 'L {} octalrights dup print free SPACE
@mydir 'L {} executable { .">" }{ SPACE } SPACE
@mydir 'L {} getfilename dup 67 stub print SPACE drop
@mydir 'L {} broken { ."--->" }{ ."===>" } SPACE
@mydir 'L {} destination dup 30 stub print drop
NL |}
@points sprint
@mydir ~L { ."Total: " @mydir ~L #g print ." symlinks.\n"
}
}
@vonal sprint
."Size, alltogether = " @mydir alltotal sbr §ifcolored NL
@vonal sprint
@mydir free
."Free spaces:   /* Total size of the filesystem is : " @mypath filesystemsize dup sto filsize sbr §ifcolored ." */\n"
."  for non-privilegized use: " @mypath freenonpriv dup sbr §ifcolored
#g 100 * @filsize / ." ( " print ."% ) " NL
."  All available free space: " @mypath totalfree dup sbr §ifcolored
#g 100 * @filsize / ." ( " print ."% ) " NL
end

ifcolored:
###ifdef COLORS
coloredsize
###endif
###ifndef COLORS
#g !(#s) 21 >|
###endif
dup sprint free
rts

{ „filsize” }
{ „mydir” }
{ „mypath” }
{ „temp” }
{ „makestring” #s * dup 10 !+ swap free #g = }
Output:

An example output:

Directories:
0775 arrays                                vz:vz     2020.05.08 15:00:34 P  
0775 Brainfukk                             vz:vz     2020.03.28 16:06:37 Szo
0775 examples                              vz:vz     2020.06.07 19:26:48 V  
0775 furorfonts                            vz:vz     2020.05.09 10:46:19 Szo
0775 furorheaders                          vz:vz     2020.06.02 00:37:36 K  
0775 hasznosvolt                           vz:vz     2020.05.09 15:19:09 Szo
0775 headers                               vz:vz     2020.05.30 19:20:18 Szo
0775 kiserleti                             vz:vz     2020.05.13 19:24:23 Sze
0775 libraries                             vz:vz     2020.06.07 19:25:25 V  
0775 OLD                                   vz:vz     2020.06.07 23:29:10 V  
0775 tests                                 vz:vz     2020.03.16 23:00:47 H  
0775 useful                                vz:vz     2020.06.07 23:24:42 V  
............................................................
Total: 12 subdirectories.
------------------------------------------------------------------------------------------
Regular files:
0664                  3313   __furor.c                             vz:vz     2020.05.23 14:30:17 Szo
0664                871113   A_Furor_programozasi_nyelv.odt        vz:vz     2020.06.07 23:24:25 V  
0664                  9046   castingoperators.c                    vz:vz     2020.04.28 16:05:35 K  
0664                 32414   cmpoperators.c                        vz:vz     2020.06.06 18:23:20 Szo
0664                  2424   dir.upu                               vz:vz     2020.06.09 09:47:00 K  
0664                  1187   eca.upu                               vz:vz     2020.06.07 23:13:06 V  
0664                  2630   fonttest.upu                          vz:vz     2020.05.24 23:43:48 V  
0775                 10756 > furor                                 vz:vz     2020.06.07 19:25:25 V  
0664                    81   furordescriptorlength.upu             vz:vz     2020.06.07 19:26:19 V  
0664                 85399   furorrun.c                            vz:vz     2020.06.07 19:25:12 V  
0664                   509   furt.upu                              vz:vz     2020.06.02 00:31:17 K  
0664                 13150   jumpingtable.c                        vz:vz     2020.06.06 20:58:26 Szo
0644                563834   Kajjam700.png                         vz:vz     2013.07.31 01:38:01 Sze
0664                 21392   keywords.c                            vz:vz     2020.06.07 19:23:58 V  
0664                  5399   labelledloops.c                       vz:vz     2020.05.28 09:43:50 Cs 
0664                  2040   langtonsant.upu                       vz:vz     2020.05.25 15:25:41 H  
0664                  2581   libraries.sh                          vz:vz     2020.06.02 00:28:27 K  
0664                    84   link.txt                              vz:vz     2020.06.02 00:56:22 K  
0664                    41   lowercasealphabet.upu                 vz:vz     2020.06.05 22:40:34 P  
0664                  1035   Makefile                              vz:vz     2020.04.09 22:24:12 Cs 
0664                  1646   makeup.c                              vz:vz     2020.06.01 20:09:30 H  
0664                   884   mandelbrot9.upu                       vz:vz     2020.06.06 18:06:48 Szo
0664                 22767   maze.upu                              vz:vz     2020.05.04 18:26:14 H  
0664                   669   myxmodmap.fur                         vz:vz     2020.05.11 18:51:59 H  
0664                   240   neglect.upu                           vz:vz     2020.05.16 19:33:13 Szo
0644                131072   pibinary.bin                          vz:vz     2018.06.07 22:36:54 Cs 
0664                  1270   pngxproba.upu                         vz:vz     2020.05.09 20:08:50 Szo
0664                  1275   pngxproba2.upu                        vz:vz     2020.05.06 21:15:24 Sze
0644                   504   preinitpostmortem.c                   vz:vz     2020.03.26 13:03:12 Cs 
0644               5891695   primszamok.txt                        vz:vz     2017.01.23 18:33:14 H  
0664                   954   statusbar.upu                         vz:vz     2020.06.08 21:11:06 H  
0664                  3447   t.txt                                 vz:vz     2020.06.08 22:00:05 H  
0644                  7401   UPU.syntax                            vz:vz     2020.05.25 22:34:33 H  
0664                  2000   verify.upu                            vz:vz     2020.04.29 21:10:02 Sze
0664                   188   windowsresolutions.upu                vz:vz     2020.06.02 00:36:08 K  
0664                   816   xproba.upu                            vz:vz     2020.05.11 11:39:39 H  
0664                   931   xprobafur.upu                         vz:vz     2020.05.11 18:49:16 H  
............................................................
Total: 37 regular files. TotalSize =               7696187
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
Size, alltogether =               7745339
------------------------------------------------------------------------------------------
Free spaces:   /* Total size of the filesystem is :          126693117952 */
  for non-privilegized use:           13951995904 ( 11% ) 
  All available free space:           20411224064 ( 16% ) 

It is not visible on the output above, but the digits in the filesize are colored, each 3 digits has different color.

Peri

The following program lists just the subdirectories, regular files and symlinks, because I do no need the other gizmos generally, but based on these abovementioned file types it is easy to expand with them, if it is necessary.

The output is indeed sorted, but not all filetypes alltogether: the sorting algorythm is invoked for the different filetypes separately, because it is the way I like it!

###sysinclude standard.uh
###sysinclude args.uh
###sysinclude io.uh
###sysinclude str.uh

###define COLORS
// delete the COLORS directive above if you do not want colored output!
#g argc 3 < { "." }{ 2 argv } sto mypath
@mypath 'd inv istrue { ."The given directory doesn't exist! Exited.\n" end }
@mypath getdir { ."Cannot load the dir! Aborted.\n" end } sto mydir
'- 90 *... sto vonal
'. 60 *... sto points

@mydir ~d {
."Directories:\n"
@mydir ~d  {{ #s
@mydir 'd {{}} octalrights dup print inv mem SPACE
@mydir 'd {{}} getfilename dup 67 mc print SPACE drop
@mydir 'd {{}} groupname ': !+
@mydir 'd {{}} ownername dup sto temp + dup 10 mc print inv mem @temp inv mem
@mydir 'd {{}} mtime dup print inv mem
NL }}
@points sprintnl
@mydir ~d { ."Total: " @mydir ~d #g print ." subdirectories.\n" }
@vonal sprintnl
}

@mydir ~r {
."Regular files:\n"
@mydir ~r  {{ #s
@mydir 'r {{}} octalrights dup print inv mem SPACE
@mydir 'r {{}} getfilesize sbr §ifcolored
@mydir 'r {{}} executable { ." >" }{ ."  " } SPACE
@mydir 'r {{}} getfilename dup 67 mc print SPACE drop
@mydir 'r {{}} groupname ': !+
@mydir 'r {{}} ownername dup sto temp + dup 10 mc print inv mem @temp inv mem
@mydir 'r {{}} mtime dup print inv mem
NL }}
@points sprintnl
@mydir ~r { ."Total: " @mydir ~r #g print ." regular files. "
."TotalSize = " @mydir 'r totalsize sbr §ifcolored NL
}
@vonal sprintnl
}
@mydir ~L {
."Symlinks:\n"
@mydir ~L  {{ #s
@mydir 'L {{}} octalrights dup print inv mem SPACE
@mydir 'L {{}} executable { .">" }{ SPACE } SPACE
@mydir 'L {{}} getfilename dup 67 mc print SPACE drop
@mydir 'L {{}} broken { ."--->" }{ ."===>" } SPACE
@mydir 'L {{}} destination dup 30 mc print drop
NL }}
@points sprintnl
@mydir ~L { ."Total: " @mydir ~L #g print ." symlinks.\n"
}
}
@vonal sprintnl
."Size, alltogether = " @mydir alltotal sbr §ifcolored NL
@vonal sprintnl


@mydir inv mem

."free spaces:   /* Total size of the filesystem is : " @mypath filesystemsize dup sto filsize sbr §ifcolored ." */\n"
."  for non-privilegized use: " @mypath freenonpriv dup sbr §ifcolored
#g 100 * @filsize / ." ( " print ."% ) " NL
."  All available free space: " @mypath totalfree dup sbr §ifcolored
#g 100 * @filsize / ." ( " print ."% ) " NL
@vonal inv mem
end

ifcolored:
###ifdef COLORS
coloredsize
###endif
###ifndef COLORS
#g !(#s) 21 >|
###endif
dup sprint inv mem
rts

{ „filsize” }
{ „mydir” }
{ „mypath” }
{ „temp” }
{ „vonal”  }
{ „points” }
Output:
Directories:
0775 arrays                                                              vz:vz     2020.11.15 22:44:49 V  
0775 examples                                                            vz:vz     2021.02.05 22:58:48 P  
0775 headers                                                             vz:vz     2021.01.19 20:34:07 K  
0775 inaneheaders                                                        vz:vz     2021.02.21 18:59:46 V  
0775 keyboardlayout_files                                                vz:vz     2021.09.10 21:51:11 P  
0775 libraries                                                           vz:vz     2021.09.10 22:20:04 P  
0775 Peri_newlinkerhez                                                   root:root 2022.06.19 18:53:37 V  
0775 patterns                                                            vz:vz     2021.02.21 17:24:35 V  
0775 perifonts                                                           vz:vz     2020.05.09 10:46:19 Szo
0775 tests                                                               vz:vz     2020.11.08 14:44:31 V  
0775 useful                                                              vz:vz     2022.01.27 12:16:31 Cs 
............................................................
Total: 11 subdirectories.
------------------------------------------------------------------------------------------
Regular files:
0664                  3379   __peri.c                                                            vz:vz     2020.11.08 14:35:28 V  
0664                938037   A_Peri_programozasi_nyelv.odt                                       vz:vz     2022.02.16 16:10:56 Sze
0664                  9185   castingoperators.c                                                  vz:vz     2020.12.30 20:19:48 Sze
0664                 27148   inanerun.c                                                          vz:vz     2021.01.26 12:52:53 K  
0664                 14998   jumpingtable.c                                                      vz:vz     2021.01.26 12:52:19 K  
0664                 15862   keywords.c                                                          vz:vz     2021.01.26 12:46:02 K  
0664                  3110   libraries.sh                                                        vz:vz     2020.12.04 02:46:13 P  
0664                  1114   Makefile                                                            vz:vz     2020.11.08 14:12:28 V  
0664                   257   mybmi.upu                                                           vz:vz     2022.01.27 12:15:03 Cs 
0775                 10279 > peri                                                                vz:vz     2021.09.10 22:20:04 P  
0664                 34225   postfixoperators.c                                                  vz:vz     2021.01.01 00:16:45 P  
0644                   563   preinitpostmortem.c                                                 vz:vz     2020.10.25 15:48:55 V  
0664                   119   printitself.upu                                                     vz:vz     2023.03.21 22:23:24 K  
0664                929840   The_Peri_programming_language.odt                                   vz:vz     2021.09.10 22:23:22 P  
0644                  8357   UPU.syntax                                                          vz:vz     2021.01.06 18:00:58 Sze
0664                  2199   verify.upu                                                          vz:vz     2020.11.29 23:07:42 V  
............................................................
Total: 16 regular files. TotalSize =               1998672
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
Size, alltogether =               2043728
------------------------------------------------------------------------------------------
free spaces:   /* Total size of the filesystem is :          126693117952 */
  for non-privilegized use:           35734585344 ( 28% ) 
  All available free space:           42193813504 ( 33% ) 

It is not visible on the output above, but the digits in the filesize are colored, each 3 digits has different color.

Gambas

Public Sub Main()
Dim sDir As String[] = Dir(User.Home &/ "test").Sort()

Print sDir.Join(gb.NewLine)

End

Output:

a.txt
b.txt
c.txt
d.txt
e.txt

Go

package main

import (
	"fmt"
	"log"
	"os"
	"sort"
)

func main() {
	f, err := os.Open(".")
	if err != nil {
		log.Fatal(err)
	}
	files, err := f.Readdirnames(0)
	f.Close()
	if err != nil {
		log.Fatal(err)
	}
	sort.Strings(files)
	for _, n := range files {
		fmt.Println(n)
	}
}

Haskell

Works with: GHC version 7.8.3
import Control.Monad
import Data.List
import System.Directory

dontStartWith = flip $ (/=) . head

main = do
  files <- getDirectoryContents "."
  mapM_ putStrLn $ sort $ filter (dontStartWith '.') files

J

See the dir.ijs script for a full description of the interface for dir:

   dir ''       NB. includes properties
   >1 1 dir ''  NB. plain filename as per task

Java

This is a generic implementation using the basic File methods.

import java.io.File;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;

public class Ls {
    public static void main(String[] args) throws Exception {
        Ls ls = new Ls("/");
        System.out.println(ls);
    }

    private final File directory;
    private final List<File> list;

    public Ls(String path) throws Exception {
        directory = new File(path);
        if (!directory.exists())
            throw new Exception("Path not found '%s'".formatted(directory));
        if (!directory.isDirectory())
            throw new Exception("Not a directory '%s'".formatted(directory));
        list = new ArrayList<>(List.of(directory.listFiles()));
        /* place the directories first */
        list.sort((fileA, fileB) -> {
            if (fileA.isDirectory() && fileB.isFile()) {
                return -1;
            } else if (fileA.isFile() && fileB.isDirectory()) {
                return 1;
            }
            return 0;
        });
    }

    private String size(long bytes) {
        if (bytes > 1E9) {
            return "%.1fG".formatted(bytes / 1E9d);
        } else if (bytes > 1E6) {
            return "%.1fM".formatted(bytes / 1E6d);
        } else if (bytes > 1E3) {
            return "%.1fK".formatted(bytes / 1E3d);
        } else {
            return "%d".formatted(bytes);
        }
    }

    @Override
    public String toString() {
        StringBuilder string = new StringBuilder();
        Formatter formatter = new Formatter(string);
        /* add parent and current directory listings */
        list.add(0, directory.getParentFile());
        list.add(0, directory);
        /* generate total used space value */
        long total = 0;
        for (File file : list) {
            if (file == null) continue;
            total += file.length();
        }
        formatter.format("total %s%n", size(total));
        /* generate output for each entry */
        int index = 0;
        for (File file : list) {
            if (file == null) continue;
            /* generate permission columns */
            formatter.format(file.isDirectory() ? "d" : "-");
            formatter.format(file.canRead() ? "r" : "-");
            formatter.format(file.canWrite() ? "w" : "-");
            formatter.format(file.canExecute() ? "x" : "-");
            /* include size */
            formatter.format("%7s ", size(file.length()));
            /* modification timestamp */
            formatter.format("%tb %1$td %1$tR ", file.lastModified());
            /* file or directory name */
            switch (index) {
                case 0 -> formatter.format(".");
                case 1 -> formatter.format("..");
                default -> formatter.format("%s", file.getName());
            }
            if (file.isDirectory())
                formatter.format(File.separator);
            formatter.format("%n");
            index++;
        }
        formatter.flush();
        return string.toString();
    }
}
total 22.3K
dr-x    154 Feb 13 02:48 ./
dr-x  10.9K Apr 14 20:17 ../
dr-x      0 Dec 09 14:15 boot/
dr-x    660 May 12 20:48 dev/
dr-x   2.3K May 12 20:48 etc/
dr-x     12 Apr 14 20:12 home/
dr-x    614 Apr 15 15:00 lib/
dr-x   1.1K Apr 15 15:00 lib32/
dr-x     46 Feb 13 02:48 lib64/
dr-x   1.1K Apr 15 15:00 libx32/
dr-x      0 Feb 13 02:47 media/
dr-x     32 Apr 14 20:12 mnt/
dr-x     40 Apr 14 20:18 opt/
dr-x      0 May 12 20:48 proc/
d---     30 Feb 13 02:47 root/
dr-x    400 May 12 20:48 run/
dr-x   4.2K Feb 13 02:48 sbin/
dr-x      0 Feb 13 02:47 srv/
dr-x      0 May 12 20:48 sys/
drwx    566 May 13 00:41 tmp/
dr-x    116 Feb 13 02:47 usr/
dr-x     90 Feb 13 02:47 var/


An alternate demonstration

Works with: Java version 11
package rosetta;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class UnixLS {

	public static void main(String[] args) throws IOException {
		Files.list(Path.of("")).sorted().forEach(System.out::println);
	}
}

The challenge does not state that the files must be sorted in case-insensitive order, and the majority of solutions in other languages do not bother with same. The above can be expanded to sort case-insensitively by mapping Path to String and using the predefined String Comparator:

Files.list(Path.of("")).map(Path::toString).sorted(String.CASE_INSENSITIVE_ORDER).forEach(System.out::println);

JavaScript

Works with: Node.js version 4.3.2+
const fs = require('fs');
fs.readdir('.', (err, names) => names.sort().map( name => console.log(name) ));

Jsish

Jsi provides a File module with a glob method.

# help File.glob
File.glob(pattern:regexp|string|null='*', options:function|object|null=void):array
Return list of files in dir with optional pattern match.
With no arguments (or null) returns all files/directories in current directory.
The first argument can be a pattern (either a glob or regexp) of the files to return.
When the second argument is a function, it is called with each path, and filter on false.
Otherwise second argument must be a set of options.

To emulate ls, sorted, one entry per line:

puts(File.glob().sort().join('\n'));

Julia

# v0.6.0

for e in readdir() # Current directory
    println(e)
end

# Same for...
readdir("~") # Read home directory
readdir("~/documents")

Kotlin

// Version 1.2.41

import java.io.File

fun ls(directory: String) {
    val d = File(directory)
    if (!d.isDirectory) {
        println("$directory is not a directory")
        return
    }
    d.listFiles().map { it.name }
                 .sortedBy { it.toLowerCase() }  // case insensitive
                 .forEach { println(it) }
}

fun main(args: Array<String>) {
    ls(".")  // list files in current directory, say
}

Ksh

#!/bin/ksh

# List everything in the current folder (sorted), similar to `ls` 

#	# Variables:
#
targetDir=${1:-/tmp/foo}

 ######
# main #
 ######

cd ${targetDir}
for obj in *; do
	print ${obj}
done

LiveCode

set the defaultFolder to "/foo"
put the folders & the files 
set the defaultFolder to "/foo/bar"
put the folders & the files

Lua

Using LuaFileSystem - available in LuaRocks, ULua, major Linux distro repos, etc, etc.

require("lfs")
for file in lfs.dir(".") do print(file) end

Mathematica /Wolfram Language

Column[FileNames[]]

Nanoquery

import Nanoquery.IO
import sort

fnames = sort(new(File).listDir("."))

for i in range(0, len(fnames) - 1)
    println fnames[i]
end
Output:
.\nanoquery-2.3_1866
.\notes.txt
.\nq.bat
.\nq.vim
.\rosetta-code

Nim

from algorithm import sorted
from os import walkPattern
from sequtils import toSeq

for path in toSeq(walkPattern("*")).sorted:
  echo path

Objeck

class Test {
  function : Main(args : String[]) ~ Nil {
    file_names := System.IO.File.Directory->List(".");
    each(i : file_names) {
      file_name := file_names[i];
      if(System.IO.File.Directory->Exists(file_name)) {
        file_name += '/';
      };
      file_name->PrintLine();
    };
  }
}

OCaml

let () =
  Array.iter print_endline (
    Sys.readdir Sys.argv.(1) )
Output:
$ cd /foo/bar
$ ocaml ls.ml
1
2
a
b

PARI/GP

GP doesn't have this capability so we can either use the shell or PARI. For the latter see C; for the former:

system("dir/b/on")

in DOS/Windows or

system("ls")

in *nix.

Pascal

This is the example in the Turbo Pascal 4 manual. With Turbo Pascal and old-style DOS file names, all file names come out in capitals, further, names not fitting into the "8.3" style (of up to eight characters followed by an extension of up to three characters) are presented with ad-hoc names fitting that style, so for example, Tab2Comma.exe comes out as TAB2CO~1.EXE. The same source file compiles unchanged via the Free Pascal compiler, whereupon long file names appear with capitals and lower-case letters rather than all-capitals.

When tested via Windows XP, the names came out in sorted order (ignoring case) however in earlier systems the files would be presented in entry order. That is, if files a, c, b were saved, they would be named in that order. Then, if file c were deleted and then a file named x were added, they would be named in the order a, x, b. In this case, a scheme for saving an unknown number of names (of unknown length) would be needed so that they could be sorted. Perhaps some linked-list with an insertionsort for each added name...

Program ls;	{To list the names of all files/directories in the current directory.}
 Uses DOS;
 var DirInfo: SearchRec;	{Predefined. See page 403 of the Turbo Pascal 4 manual.}
 BEGIN
  FindFirst('*.*',AnyFile,DirInfo);	{AnyFile means any file name OR directory name.}
  While DOSerror = 0 do			{Result of FindFirst/Next not being a function, damnit.}
   begin
    WriteLn(DirInfo.Name);
    FindNext(DirInfo);
   end;
 END.

Perl

opendir my $handle, '.' or die "Couldnt open current directory: $!";
while (readdir $handle) {
    print "$_\n";
}
closedir $handle;

Alternatively, using glob:

print "$_\n" for glob '*';
print "$_\n" for glob '* .*';  # If you want to include dot files

Phix

without js -- (file i/o)
pp(dir("."),{pp_Nest,1,pp_IntCh,false})
Output:
{{`.`, `d`, 0,2020,6,11,13,25,13},
 {`..`, `d`, 0,2020,6,11,13,25,13},
 {`.hg`, `d`, 0,2020,4,4,6,42,6},
 {`.hgignore`, `a`, 18898,2020,4,4,13,57,37},
 {`1KB.zip`, `a`, 1024,2019,7,28,15,30,45},
 {`a.exe`, `a`, 133889,2019,8,24,20,27,21},
 {`address.sqlite`, `a`, 12288,2018,7,20,19,44,34},
 {`alice_oz.txt`, `a`, 336926,2017,3,15,19,12,24},
 {`animation.svg`, `a`, 900,2019,5,25,12,49,14},
...etc

just names

without js -- (file i/o)
?vslice(dir("."),D_NAME)
Output:
{".","..",".hg",".hgignore","1KB.zip","a.exe","address.sqlite","alice_oz.txt","animation.svg",...}

prettier output

Each element of dir() can be indexed with D_NAME, D_ATTRIBUTES, D_SIZE, D_YEAR, D_MONTH, D_DAY, D_HOUR, D_MINUTE, and D_SECOND, and of course you can easily format these things a bit nicer. Of course there is no way to get a proper directory listing in javascript, so for pwa/p2js we'll just create some fake results.

with javascript_semantics
function dirf(string path, integer date_type=D_MODIFICATION)
    if platform()=JS then
        return {{`.`, `d`, 0,2022,2,11,01,09,13},
                {`..`, `d`, 0,2022,2,11,01,09,13},
                {`.fake`, `a`, 5,2021,6,1,6,42,6},
                {`directory`, `a`, 18898,2020,4,4,13,57,37},
                {`for.p2js`, `a`, 1024,2019,7,28,15,30,45}}
    else
        return dir(path,date_type)
    end if
end function

include builtins\timedate.e
set_timedate_formats({"hh:mmpm Ddd Mmm ddth YYYY"})
object d = dirf(".")
if d!=-1 then
    printf(1,"%-20s %s %10s  %s\n",{"-- name --","attr","size","-- time and date --"})
    for i=1 to length(d) do
        sequence di = d[i]
        string name = di[D_NAME],
               attr = di[D_ATTRIBUTES],
               size = file_size_k(d[i][D_SIZE]),
               tdte = format_timedate(d[i][D_YEAR..$])
        printf(1,"%-20s %=4s %10s  %s\n",{name,attr,size,tdte})
    end for
end if
Output:
-- name --           attr       size  -- time and date --
.                     d            0  01:25pm Thu Jun 11th 2020
..                    d            0  01:25pm Thu Jun 11th 2020
.hg                   d            0  06:42am Sat Apr 04th 2020
.hgignore             a      18.46KB  01:57pm Sat Apr 04th 2020
1KB.zip               a          1KB  03:30pm Sun Jul 28th 2019
a.exe                 a     130.75KB  08:27pm Sat Aug 24th 2019
address.sqlite        a         12KB  07:44pm Fri Jul 20th 2018
alice_oz.txt          a     329.03KB  07:12pm Wed Mar 15th 2017
animation.svg         a          900  12:49pm Sat May 25th 2019
...etc

or under pwa/p2js:

-- name --           attr       size  -- time and date --
.                     d            0  01:09am Fri Feb 11th 2022
..                    d            0  01:09am Fri Feb 11th 2022
.fake                 a            5  06:42am Tue Jun 01st 2021
directory             a      18.46KB  01:57pm Sat Apr 04th 2020
for.p2js              a          1KB  03:30pm Sun Jul 28th 2019

PHP

This will output all the filenames in the current directory.

<?php
foreach(scandir('.') as $fileName){
    echo $fileName."\n";
}

Picat

import os, util.
main =>
  println(ls()),
  println(ls("foo/bar")).

ls() = ls(".").
ls(Path) = [F : F in listdir(Path), F != ".",F != ".."].sort.join('\n').


PicoLisp

(for F (sort (dir))
   (prinl F) )

Pike

foreach(sort(get_dir()), string file)
    write(file +"\n");

PowerShell

# Prints Name, Length, Mode, and LastWriteTime
Get-ChildItem | Sort-Object Name | Write-Output

# Prints only the name of each file in the directory
Get-ChildItem | Sort-Object Name | ForEach-Object Name | Write-Output

PureBasic

NewList lslist.s()

If OpenConsole("ls-sim")
  If ExamineDirectory(0,GetCurrentDirectory(),"*.*")
    While NextDirectoryEntry(0)
      AddElement(lslist()) : lslist()=DirectoryEntryName(0)
    Wend
    FinishDirectory(0)
    SortList(lslist(),#PB_Sort_Ascending)
    ForEach lslist()
      PrintN(lslist())
    Next    
  EndIf
  Input()
EndIf

Python

>>> import os
>>> print('\n'.join(sorted(os.listdir('.'))))
DLLs
Doc
LICENSE.txt
Lib
NEWS.txt
README.txt
Scripts
Tools
include
libs
python.exe
pythonw.exe
tcl
>>>

R

cat(paste(list.files(), collapse  = "\n"), "\n")
cat(paste(list.files("bar"), collapse = "\n"), "\n")
Output:
bar 
1
2
a
b 

Racket

Ooh... warning... if you run the test module (either with DrRacket with the test module automatically running, or with raco test ls.rkt, then the example directory tree is built but not torn down.

#lang racket/base

;; Racket's `directory-list' produces a sorted list of files
(define (ls) (for-each displayln (directory-list)))

;; Code to run when this file is running directly
(module+ main
  (ls))

(module+ test
  (require tests/eli-tester racket/port racket/file)
  (define (make-directory-tree)
    (make-directory* "foo/bar")
    (for ([f '("1" "2" "a" "b")])
      (with-output-to-file (format "foo/bar/~a"f) #:exists 'replace newline)))
  (make-directory-tree)
  (define (ls/str dir)
    (parameterize ([current-directory dir]) (with-output-to-string ls)))
  (test (ls/str "foo") => "bar\n"
        (ls/str "foo/bar") => "1\n2\na\nb\n"))

Both tests pass.

Raku

(formerly Perl 6)

There is a dir builtin command which returns a list of IO::Path objects. We stringify them all with a hyperoperator before sorting the strings.

.say for sortdir

REXX

The following program works under Windows and uses the Windows   DIR   command to list a bare─bones sorted list.

Notes on the options used for the   (Microsoft Windows®)   DIR   command:

  •   b   is for bare format (no heading information or summary).
  •   o   is for order, and it orders (sorts alphabetically) by file Name.
/*REXX program lists contents of current folder  (ala mode UNIX's  LS). */
'DIR  /b  /oN'                         /*use Windows DIR: sorts & lists.*/
                                       /*stick a fork in it, we're done.*/
output :
1
2
3
4

RPL

VARS returns all the files and folders in the current directory, but not sorted. A few additional words are then needed to turn names into strings, sort the strings and come back to names.

≪ VARS LIST→ → len 
  ≪ 1 len FOR n →STR len ROLL NEXT
     len 1 FOR n 
        1 n 1 - START 
           IF DUP2 > THEN SWAP END n ROLLD NEXT 
        n ROLLD -1 STEP
     1 len FOR n STR→ len ROLL NEXT
     len →LIST
≫ ≫ ‘LS’ STO

Ruby

Dir.foreach("./"){|n| puts n}

This will output all files including hidden ones e.g. '.' and '..'.

Run BASIC

files #f, DefaultDir$ + "\*.*" 	' RunBasic Default directory.. Can be any directroy
print "rowcount: ";#f ROWCOUNT()		' how many rows in directory
#f DATEFORMAT("mm/dd/yy") 			'set format of file date or not
#f TIMEFORMAT("hh:mm:ss") 			'set format of file time or not
count = #f rowcount()
for i = 1 to count				' loop thru the row count
print "info: ";#f nextfile$()			' file info         
print "name: ";#f NAME$()			' Name of file
print "size: ";#f SIZE()			' size
print "date: ";#f DATE$()			' date
print "time: ";#f TIME$()			' time
print "isdir: ";#f ISDIR()			' 1 = is a directory
next

This will output RunBasics Default Directory.. It can be any directory

rowcount: 30
info: antiGram1.bas,1743,08/02/16,08:34:50,
name: antiGram1.bas
size: 1743
date: 08/02/16
time: 08:34:50
isdir: 0
info: avionics.db,0,05/09/16,09:02:01,
name: avionics.db
size: 0
date: 05/09/16
time: 09:02:01
isdir: 0
...

Rust

use std::{env, fmt, fs, process};
use std::io::{self, Write};
use std::path::Path;

fn main() {
    let cur = env::current_dir().unwrap_or_else(|e| exit_err(e, 1));
    let arg = env::args().nth(1);
    print_files(arg.as_ref().map_or(cur.as_path(), |p| Path::new(p)))
        .unwrap_or_else(|e| exit_err(e, 2));
}

#[inline]
fn print_files(path: &Path) -> io::Result<()> {
    for x in try!(fs::read_dir(path)) {
        println!("{}", try!(x).file_name().to_string_lossy());
    }
    Ok(())
}

#[inline]
fn exit_err<T>(msg: T, code: i32) -> ! where T: fmt::Display {
    writeln!(&mut io::stderr(), "{}", msg).expect("Could not write to stderr");
    process::exit(code)
}
Output:
$ mkdir -p foo/bar
$ ./unix_ls
foo
unix_ls
$ cd foo/bar
$ touch a b 1 2
$ cd ../..
$ ./unix_ls foo
bar
$ ./unix_ls foo/bar
1
2
a
b

S-lang

variable d = listdir(getcwd()), p;
foreach p (array_sort(d))
  () = printf("%s\n", d[p] );

Scala

Output:
scala> new java.io.File("/").listFiles.sorted.foreach(println)
/bin
/boot
/core
/dev
/etc
/home
/lib
/lib64
/local
/lost+found
/media
/mnt
/opt
/proc
/root
/run
/sbin
/selinux
/srv
/sys
/tmp
/user
/usr
/var 

Seed7

$ include "seed7_05.s7i";
  include "osfiles.s7i";

const proc: main is func
  local
    var string: name is "";
  begin
    for name range readDir(".") do
       writeln(name);
    end for;
  end func;

Sidef

Explicit, by opening the current working directory:

var content = [];
Dir.cwd.open.each { |file|
    file ~~ < . .. > && next;
    content.append(file);
}

content.sort.each { |file|
    say file;
}

Implicit, by using the String.glob method:

'*'.glob.each { |file|
    say file;
}

Smalltalk

cheating solution:

Works with: Smalltalk/X
Stdout printCR: ( PipeStream outputFromCommand:'ls' )

real solution:

Works with: Smalltalk/X
Stdout printCR:('.' asFilename directoryContents sort asStringWith:Character cr)

or:

'.' asFilename directoryContents sort do:#printCR

full 'ls -l' output:

Works with: Smalltalk/X
dir := '.' asFilename.
dir directoryContentsAsFilenames sort do:[:fn |
    |line|
    " 
     generate a line of the form of ls -l:
         drwxrwxrwx    user  group     size  date time name
     where year is printed if not current, time of day otherwise
    " 
    line := String streamContents:[:s |
        |accessRights|

        s nextPut:(fn isDirectory ifTrue:[$d] ifFalse:[$-]).
        accessRights := fn symbolicAccessRights.
        #(  readUser writeUser executeUser 
            readGroup writeGroup executeGroup
            readOthers writeOthers executeOthers
         ) 
        with:'rwxrwxrwx' 
        do:[:eachRight :charToPrint |
            s nextPut:((accessRights includes:eachRight) ifTrue:[charToPrint] ifFalse:[$-])
        ].
        (OperatingSystem getUserNameFromID:fn info uid) printOn:s leftPaddedTo:10.
        (OperatingSystem getGroupNameFromID:fn info gid) printOn:s leftPaddedTo:10.
        fn fileSize printOn:s leftPaddedTo:12.
        fn modificationTime year = Date today year ifTrue:[
            fn modificationTime printOn:s format:' %(dayPadded) %(ShortMonthName) %h:%m'.
        ] ifFalse:[
            fn modificationTime asDate printOn:s format:' %(dayPadded) %(ShortMonthName)  %y'.
        ].
        s space.
        s nextPutAll:fn baseName
    ].
    line printCR
].
Output:
-rw-r--r--     xxxxx     staff       18436 13 Okt 14:16 .DS_Store
-rw-r--r--     xxxxx     staff         712 13 Aug 12:58 .cvsignore
...
-rwxr--r--     xxxxx     staff        1440 22 Dez 14:33 script.st
-rwxr-xr-x     xxxxx     staff       14716 22 Dez 03:35 stx
...

Standard ML

OS.Process.system "ls -a"

Doing it all by yourself:

local   (* make a sort function *) 
  val rec insert = fn s :string =>fn [] => [s]
	| ll as h::t => if s<=h then s::ll else h::insert s t;
in 
  val rec sort = fn [] => [] | h::t => insert h (sort t)
end;

open Posix.FileSys ;
val istream = opendir "." ;
val ll =  ref [readdir istream] ;
while ( isSome (hd (!ll)) ) do  ( ll:=readdir istream :: !ll );
val result = List.map valOf (tl (!ll));
closedir istream ;

sort result;

Stata

Stata has a builtin dir command (or equivalently ls).

. dir *.dta
   6.3k   6/12/17 14:26  auto.dta
   2.3k   8/10/17  7:34  titanium.dta
   6.0k   8/12/17  9:28  trend.dta

Tcl

puts [join [lsort [glob -nocomplain *]] "\n"]

UNIX Shell

Using `ls` explicitly would be a cheat, since the goal of the task is to emulate this program.

A simple way to list files in the current directory without using `ls` is to use filename expansion (a.k.a. "globbing").

echo *

To print each filename on a separate line, use a loop:

for f in *; do echo "$f"; done

If you want this output sorted, then use `sort`:

for f in *; do echo "$f"; done |sort

An other possibility is to use GNU coreutils' `stat`:

stat -c %n * |sort

Ursa

decl file f
decl string<> fnames
set fnames (sort (f.listdir "."))

for (decl int i) (< i (size fnames)) (inc i)
        out fnames<i> endl console
end for

V (Vlang)

import os

fn main() {
	contents := os.ls('.')?
    println(contents)
}

Wren

import "io" for Directory

var path = "./" // or whatever

// Note that output is automatically sorted using this method. 
Directory.list(path).each { |f| System.print(f) }

XPL0

Works on Raspberry Pi.

string 0;
char S;
[S:= "ls";
asm {   ldr     r0, S
        bl      system
    }
]

zkl

File.glob("*").sort()

Lists all files and directories in the current directory. If you only want a list of files:

File.glob("*",0x8).sort()
Output:
L("README","superball","testThemAll.log","zkl.exe","zkl_tests.zip","zkl_vm_src.zip")

The glob method uses Unix shell wild cards.

The globular method recurses down through the directories. It can send results to objects, functions, methods, threads, etc, etc. To get a sorted list of all the directories under the "Src" directory:

File.globular("Src",*,True,0x10,List).sort().concat("\n")
Output:
Src/Compiler/
Src/Misc/
Src/Test/
Src/Time/
Src/Utils/
Src/ZenKinetic/
Src/ZenKinetic/Frame_O_Matic/
Src/ZenKinetic/GBalls/
Src/ZenKinetic/Twist and Draw/
Src/ZenKinetic/ZEd