Unix/ls: Difference between revisions
m →{{header|REXX}}: moved some comments around, changed wording in the REXX section header. |
Drkameleon (talk | contribs) |
||
Line 232:
=={{header|Arturo}}==
<lang
=={{header|AWK}}==
|
Revision as of 10:15, 20 February 2021
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
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.
<lang 8080asm>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:</lang>
8th
<lang forth> "*" f:glob ' s:cmp a:sort "\n" a:join . </lang>
Ada
<lang 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;</lang>
Aime
<lang 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");</lang>
Arturo
<lang rebol>print list "."</lang>
AWK
"BEGINFILE" is a gawk-extension
<lang AWK>
- syntax: GAWK -f UNIX_LS.AWK * | SORT
BEGINFILE {
printf("%s\n",FILENAME) nextfile
} END {
exit(0)
} </lang>
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
To replicate 'ls .'
gawk -lreaddir 'BEGIN { FS = "/" } {print $2}' .
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
<lang freebasic>' 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</lang>
C
C does not have any os-independent way of reading a directory. The following uses readdir and should work on any Unix system. <lang C>
- 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;
} </lang>
C#
<lang csharp>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); } } }
}</lang>
C++
<lang cpp>
- 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';
} </lang>
Clojure
<lang clojure>(def files (sort (filter #(= "." (.getParent %)) (file-seq (clojure.java.io/file ".")))))
(doseq [n files] (println (.getName n)))</lang>
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.
<lang lisp>(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)))</lang>
D
<lang 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;
}</lang>
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. <lang lisp>
- 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
</lang>
Elixir
<lang 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</lang>
Erlang
<lang 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] </lang>
F#
Works with .NET framework 4.
<lang fsharp>let ls = DirectoryInfo(".").EnumerateFileSystemInfos() |> Seq.map (fun i -> i.Name) |> Seq.sort |> Seq.iter (printfn "%s")</lang>
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: <lang forth>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 ;</lang>
Given that requirement, we must first generate a sorted array of filenames:
<lang forth>: 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 ;
</lang>
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! <lang Fortran> 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." </lang>
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: <lang Fortran> 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</lang>
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.
FunL
<lang funl>import io.File
for f <- sort( list(File( "." ).list()).filterNot(s -> s.startsWith(".")) )
println( f )</lang>
- 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!
<lang Furor>
- 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 = } </lang>
- 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.
Gambas
<lang gambas>Public Sub Main() Dim sDir As String[] = Dir(User.Home &/ "test").Sort()
Print sDir.Join(gb.NewLine)
End</lang> Output:
a.txt b.txt c.txt d.txt e.txt
Go
<lang 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) } }</lang>
Haskell
<lang haskell>import Control.Monad import Data.List import System.Directory
dontStartWith = flip $ (/=) . head
main = do
files <- getDirectoryContents "." mapM_ putStrLn $ sort $ filter (dontStartWith '.') files</lang>
J
See the dir.ijs script for a full description of the interface for dir
:
<lang J> dir NB. includes properties
>1 1 dir NB. plain filename as per task</lang>
Java
<lang java> 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); } } </lang>
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: <lang java> Files.list(Path.of("")).map(Path::toString).sorted(String.CASE_INSENSITIVE_ORDER).forEach(System.out::println); </lang>
JavaScript
<lang javascript>const fs = require('fs'); fs.readdir('.', (err, names) => names.sort().map( name => console.log(name) ));</lang>
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:
<lang javascript>puts(File.glob().sort().join('\n'));</lang>
Julia
<lang julia># v0.6.0
for e in readdir() # Current directory
println(e)
end
- Same for...
readdir("~") # Read home directory readdir("~/documents")</lang>
Kotlin
<lang scala>// 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
}</lang>
LiveCode
<lang LiveCode>set the defaultFolder to "/foo" put the folders & the files set the defaultFolder to "/foo/bar" put the folders & the files</lang>
Lua
Using LuaFileSystem - available in LuaRocks, ULua, major Linux distro repos, etc, etc. <lang Lua>require("lfs") for file in lfs.dir(".") do print(file) end</lang>
Mathematica
<lang Mathematica>Column[FileNames[]]</lang>
Nanoquery
<lang nanoquery>import Nanoquery.IO import sort
fnames = sort(new(File).listDir("."))
for i in range(0, len(fnames) - 1)
println fnames[i]
end</lang>
- Output:
.\nanoquery-2.3_1866 .\notes.txt .\nq.bat .\nq.vim .\rosetta-code
Nim
<lang Nim> from algorithm import sorted from os import walkPattern from sequtils import toSeq
for path in toSeq(walkPattern("*")).sorted:
echo path
</lang>
Objeck
<lang 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(); }; }
} </lang>
OCaml
<lang ocaml>let () =
Array.iter print_endline ( Sys.readdir Sys.argv.(1) )</lang>
- 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: <lang parigp>system("dir/b/on")</lang> in DOS/Windows or <lang parigp>system("ls")</lang> 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... <lang Pascal> 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.
</lang>
Perl
<lang perl>opendir my $handle, '.' or die "Couldnt open current directory: $!"; while (readdir $handle) {
print "$_\n";
} closedir $handle;</lang>
Alternatively, using glob: <lang perl>print "$_\n" for glob '*';</lang>
<lang perl>print "$_\n" for glob '* .*'; # If you want to include dot files</lang>
Phix
<lang Phix>pp(dir("."),{pp_Nest,1,pp_IntCh,false})</lang>
- 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
<lang Phix>?vslice(dir("."),D_NAME)</lang>
- 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. <lang Phi>include builtins\timedate.e set_timedate_formats({"hh:mmpm Ddd Mmm ddth YYYY"}) object d = dir(".") if d!=-1 then
printf(1,"%-20s %s %10s %s\n",{"-- name --","attr","size","-- time and date --"}) for i=1 to length(d) do printf(1,"%-20s %=4s %10s %s\n",{d[i][D_NAME],d[i][D_ATTRIBUTES],file_size_k(d[i][D_SIZE]),format_timedate(d[i][D_YEAR..$])}) end for
end if</lang>
- 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
PHP
This will output all the filenames in the current directory.
<lang php> <?php foreach(scandir('.') as $fileName){
echo $fileName."\n";
} </lang>
PicoLisp
<lang PicoLisp>(for F (sort (dir))
(prinl F) )</lang>
Pike
<lang Pike>foreach(get_dir(), string file)
write(file +"\n");</lang>
PowerShell
<lang 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</lang>
Python
<lang 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 >>> </lang>
R
<lang rsplus> cat(paste(list.files(), collapse = "\n"), "\n") cat(paste(list.files("bar"), collapse = "\n"), "\n") </lang>
- 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>#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"))</lang>
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.
<lang perl6>.say for sort ~«dir</lang>
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.
<lang rexx>/*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.*/</lang>
- output :
1 2 3 4
Ruby
<lang ruby> Dir.foreach("./"){|n| puts n} </lang> This will output all files including hidden ones e.g. '.' and '..'.
Run BASIC
<lang Runbasic>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</lang> 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
<lang 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)
}</lang>
- 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
<lang S-lang>variable d = listdir(getcwd()), p; foreach p (array_sort(d))
() = printf("%s\n", d[p] );</lang>
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
<lang 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;</lang>
Sidef
Explicit, by opening the current working directory: <lang ruby>var content = []; Dir.cwd.open.each { |file|
file ~~ < . .. > && next; content.append(file);
}
content.sort.each { |file|
say file;
}</lang>
Implicit, by using the String.glob method: <lang ruby>'*'.glob.each { |file|
say file;
}</lang>
Smalltalk
cheating solution:
<lang smalltalk>Stdout printCR: ( PipeStream outputFromCommand:'ls' )</lang> real solution:
<lang smalltalk>Stdout printCR:('.' asFilename directoryContents sort asStringWith:Character cr)</lang>or:<lang smalltalk>'.' asFilename directoryContents sort do:#printCR</lang> full 'ls -l' output:
<lang smalltalk>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
].</lang>
- 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
<lang sml>OS.Process.system "ls -a" </lang> Doing it all by yourself: <lang sml> 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; </lang>
Stata
Stata has a builtin dir command (or equivalently ls).
<lang stata>. 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</lang>
Tcl
<lang tcl>puts [join [lsort [glob -nocomplain *]] "\n"]</lang>
Ursa
<lang ursa>decl file f decl string<> fnames set fnames (sort (f.listdir "."))
for (decl int i) (< i (size fnames)) (inc i)
out fnames endl console
end for</lang>
Wren
<lang ecmascript>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) }</lang>
XPL0
Works on Raspberry Pi. <lang XPL0>string 0; char S; [S:= "ls"; asm { ldr r0, S
bl system }
]</lang>
zkl
<lang zkl>File.glob("*").sort()</lang> Lists all files and directories in the current directory. If you only want a list of files: <lang zkl>File.glob("*",0x8).sort()</lang>
- 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: <lang zkl>File.globular("Src",*,True,0x10,List).sort().concat("\n")</lang>
- 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
- Programming Tasks
- Solutions by Programming Task
- 8080 Assembly
- 8th
- Ada
- Aime
- Arturo
- AWK
- BaCon
- C
- C sharp
- C++
- Boost
- Clojure
- Common Lisp
- D
- EchoLisp
- Elixir
- Erlang
- F Sharp
- Forth
- Forth Foundation Library
- Fortran
- FunL
- Furor
- Gambas
- Go
- Haskell
- J
- Java
- JavaScript
- Jsish
- Julia
- Kotlin
- LiveCode
- Lua
- Mathematica
- Nanoquery
- Nim
- Objeck
- OCaml
- PARI/GP
- Pascal
- Perl
- Phix
- PHP
- PicoLisp
- Pike
- PowerShell
- Python
- R
- Racket
- Raku
- REXX
- Ruby
- Run BASIC
- Rust
- S-lang
- Scala
- Seed7
- Sidef
- Smalltalk
- Standard ML
- Stata
- Tcl
- Ursa
- Wren
- XPL0
- Zkl
- SQL PL/Omit
- TI-83 BASIC/Omit