{"id":20559884,"url":"https://github.com/cxw42/ls0","last_synced_at":"2026-06-08T05:31:15.315Z","repository":{"id":87958287,"uuid":"76673492","full_name":"cxw42/ls0","owner":"cxw42","description":"A \"ls\" replacement that separates results with a null terminator instead of a newline.","archived":false,"fork":false,"pushed_at":"2018-01-29T17:15:07.000Z","size":52,"stargazers_count":1,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-06T07:46:28.680Z","etag":null,"topics":["file-management","hacktoberfest","ls","null-terminator","perl"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cxw42.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-16T17:43:45.000Z","updated_at":"2023-09-08T17:18:22.000Z","dependencies_parsed_at":"2023-05-22T03:00:33.359Z","dependency_job_id":null,"html_url":"https://github.com/cxw42/ls0","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/cxw42/ls0","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cxw42%2Fls0","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cxw42%2Fls0/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cxw42%2Fls0/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cxw42%2Fls0/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cxw42","download_url":"https://codeload.github.com/cxw42/ls0/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cxw42%2Fls0/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34050225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["file-management","hacktoberfest","ls","null-terminator","perl"],"created_at":"2024-11-16T03:52:32.861Z","updated_at":"2026-06-08T05:31:15.278Z","avatar_url":"https://github.com/cxw42.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ls0: a \"ls\" that separates results with a null terminator\n\nls0 - List filenames, with each output null-terminated.\n\n# Synopsis\n\nls0 \\[options\\] \\[--\\] \\[pathspecs\\]\n\nRun ls0 --help for options, or ls0 --man for full documentation.\nBy default, if no pathspecs or atfiles are given, ls0 will:\n\n- if stdin is a tty,\n\n    list files in the current directory;\n\n- otherwise,\n\n    take NULL-separated input from stdin and list it.\n\nExample: `find . -name 'some*pattern' -print0 | ls0 -t`\ndisplays filenames matching `some*pattern`, newest first,\neven if those filenames contain special characters.\n\n# Options\n\n- **-a**\n\n    Also list files beginning with a `.`\n\n- **-A**\n\n    Also list files beginning with a `.`, except for `.` and `..`\n\n- **-b**, **--escape** (disable with **--noescape**)\n\n    Print octal escapes for special characters and backslashes\n    (which are `\\134`).\n    Implies **--eol** (newline terminators);\n    also specify **--noeol** if you still want null terminators.\n\n    By default, output is escaped if standard output is a terminal.\n\n    If multiple escaping options are given, **--noescape** controls (if specified).\n\n- **-d**\n\n    List directories as directories; don't list their contents.  Overrides **-R**.\n    Can't be used with **--rglob**.\n\n- **-e \u0026lt;field\u003e**, **--echo \u0026lt;field\u003e**\n\n    **Not yet implemented.**\n    Output **\u0026lt;field\u003e** for each file to be printed.  Multiple **-e** options\n    can be specified, and the fields will be output in that order.\n    Each field will be terminated by the output terminator (see **--eol**).\n\n- **--eol** (disable with **--noeol**)\n\n    Terminate output entries with a platform-specific end-of-line sequence\n    rather than a NULL.  May be useful with **--glob**.\n\n    By default, the terminator is NULL unless **--eol** is given or escaping is\n    active (by default or by **-b** or **--escape**).\n\n    If multiple escaping or terminator entries are given, **--noeol** controls\n    (if specified).\n\n- **--from \u0026lt;atfile\u003e**, **-@ \u0026lt;atfile\u003e**\n\n    Read the pathspecs to be processed from **atfile**; specify `-` to read from\n    standard input.  Each pathspec in **atfile** should\n    be separated by a NULL terminator (`\\0`).  This is ls\\_0\\_, after all.\n    The input is read in binary mode, so filenames can contain any non-NULL\n    character.\n\n    See [\"Reading atfiles\"](#reading-atfiles) for details.\n\n- **--fromeol \u0026lt;atfile\u003e**\n\n    As **--from**, but each pathspec in **atfile**\n    should be separated by a platform-specific end-of-line.\n\n    See [\"Reading atfiles\"](#reading-atfiles) for details.\n\n- **--glob**\n\n    Expand the provided pathspecs using perl's `File::Glob::bsd_glob`.\n    This is provided for shells that don't glob, or don't glob as you expect.\n    Make sure to quote the arguments if necessary to prevent your shell from\n    globbing before ls0 sees them.\n\n- **--leaf**\n\n    Only list leaves, i.e., files plus directories for which no lower-level files\n    are being listed.\n\n- **-r**\n\n    Reverse the order of the sort.  Cannot be used with **-U** (unsorted listing).\n\n- **-R**\n\n    Visit subdirectories recursively.  No effect if **-d** is specified.\n\n- **--rglob**\n\n    Glob in ls0 rather than (or in addition to) in the shell.  Try to glob\n    the pathspecs given on the command line in each directory visited.\n    Implies **-R** and **--glob**.  Can't be used with **-d**.\n\n- **-S**\n\n    Sort by file size, descending by default.\n\n- **-t**\n\n    Sort by time, newest first (unless **-r**).  Uses the modification time\n    unless **--time** is given.\n\n- **--time \u0026lt;timeval\u003e**\n\n    Use **\u0026lt;timeval\u003e** as the time when sorting.  Run `ls0 -t --time=?` to see\n    the list of available times.  At least **atime**, **ctime**, and **mtime**\n    are available.\n\n- **-U**\n\n    Don't sort the results - you get them in whatever order you get them.\n    This will likely be the breadth-first search order ls0 currently uses,\n    but you **shall not** make any assumptions about name order when using\n    this option.  Cannot be used with **-r**.\n\n- **--xargs**\n\n    A convenient synonym for `--from -`.  For example, instead of\n    `find ... | xargs ls`, you can use `find ... -print0 | ls0 --xargs`\n    to get the same effect with the benefits of (1) the safety NULL terminators\n    provide, and (2) support for a higher match count than the command line\n    can handle.\n\n    This is the default unless:\n\n    - the input is a tty;\n    - you have provided at least one pathspec on the command line; or\n    - you have named at least one atfile on the command line.\n\n## Reading atfiles\n\nThe **--from** and **--fromeol** options read atfiles and treat entries in those\nfiles as if those entries had been specified on the command line.  Things to\nbear in mind:\n\n- Since entries are as if specified on the command line, they are subject to\n**-d**, **-R**, and other options that affect how command-line parameters are\ntreated.  For example,\n`echo 'foo/' | ls0 --fromeol -` will list the\ncontents of directory `foo`, whereas\n`echo 'foo/' | ls0 --fromeol - -d` (with **-d**) will list the\nname of directory `foo`.\n\n    This may be an issue when piping `find` output into ls0;\n    see [\"Trimming duplicates\"](#trimming-duplicates) for details and workarounds.\n\n- The filename `-` refers to standard input.\n- You can't specify the same **atfile** for more than one\n**--from** or **--fromeol** option.\n- You **shall not** make any assumptions about the relative order of items\nlisted on the command line or in atfiles.  In any case, the output order is\ncontrolled only by any sorting options you provide.\n- **--fromeol** does not unescape any\ncharacters.  If you use this, make sure the filenames in **atfile** don't\ncontain end-of-line characters.\n- **--fromeol** uses the platform-specific newline sequence, e.g.,\n`\\r`, `\\n`, or `\\r\\n`.  If you try to read\nDOS text files on a UNIX ls0, the input entries will have extra \"\\\\r\"\ncharacters at the end of them.\n\n# Differences between GNU ls(1) and ls0(1)\n\n## New features\n\n- **-e \u0026lt;field\u003e**, **--echo \u0026lt;field\u003e**\n\n    Output only specific fields.  Each field is separated by the output terminator\n    rather than being printed together on a line.  That way a single loop can\n    read all the output values for all the matched files.\n\n- **--from \u0026lt;atfile\u003e**, **--fromeol \u0026lt;atfile\u003e**\n\n    Read input pathspecs from **atfile**.\n\n- **--glob**\n\n    Glob in ls0 rather than (or in addition to) in the shell.\n\n- **--rglob**\n\n    Glob in ls0 rather than (or in addition to) in the shell, and glob in each\n    subdir.\n\n- **--leaf**\n\n    Only list leaves.\n\n## Unsupported ls(1) features\n\nThe following GNU ls(1) options are not supported by ls0:\n\n- **-1** (print single line), **-C** (list down columns),\n**-m** (comma-separated output), **-x** (list across rows), **--format**,\n**-T**, **--tabsize**, **-w**/**--width**\n\n    We don't print these formats; we only support NULL and EOL as delimiters,\n    and don't do multicolumn or fixed column widths.\n    Our **-b** implies one line per output item.\n\n- **-l**/**-g**/**-o** (long listings), **--full-time**,\n**-s** (print sizes)\n\n    We use **-e**, instead of these options, to specify which fields to output.\n\n- **-F**/**--file-type**/**--indicator-style**/**-p** (print indicators),\n**-N**/**--literal** (print names literally), **-q** (hide control chars),\n**--show-control-chars** (print control characters raw),\n**-Q**/**--quote-name** (quote output), **--quoting-style**\n\n    We only print raw or with backslash escapes (**-b**), so we don't support these.\n\n- **--color**\n\n    Nope.  Sorry!\n\n- **-D**\n\n    Long live vi!\n\n- **--lcontext**, **-Z**, **--context**\n\n    We don't support SELinux at this time.\n\n## Differences in behaviour\n\n### Default search order\n\nls(1) sorts case-insensitively by default, e.g., `alpha, BAR, foo, QUUX`.\nWe sort on byte values without regard to case or encoding, e.g.,\n`BAR, QUUX, alpha, foo` (in ASCII).\n\n### Output format for multiple subdirectories\n\nWhen listing multiple directories, e.g., `ls foo/ bar/`, ls(1) shows:\n\n    foo:\n    file_in_foo\n\n    bar:\n    file_in_bar\n\nHowever, ls0(1) is intended for machine output, so it produces:\n\n    foo\n    foo/file_in_foo\n    bar\n    bar/file_in_bar\n\nin whatever order you have specified by the sort options.  With **-U**, for\nexample, you may get:\n\n    foo\n    bar\n    foo/file_in_foo\n    bar/file_in_bar\n\n(the breadth-first order), although you may get a different order.\n\n# Notes\n\n## Trimming duplicates\n\nThe command `find . -print0 | ls0` will\nprint two copies of every entry in `.`, since\nthe entries are printed as part of processing of `.` and also\nas the individual entries output by find(1).  (The same\nhappens with ls(1).)  To trim these duplicates, you can:\n\n- Use **-d**:\n\n    `find . -print0 | ls0 -d` will print `.` as itself, and not expand its\n    contents.\n\n- Exclude `.` from the `find` results:\n\n    `find . -name '.' -o -print0` will cause `find` to omit `.`\n    from its results.  Therefore, ls0 will not process `.`, and so will not\n    expand its contents.\n\n# Copyright\n\nCopyright (c) 2016--2018 Chris White [http://www.devwrench.com](http://www.devwrench.com)\nCC-BY-SA 3.0\n\nInspired by [https://stackoverflow.com/a/41168189/2877364](https://stackoverflow.com/a/41168189/2877364) by\nmyself, [cxw](https://stackoverflow.com/users/2877364/cxw).\nCode based in part on [http://stackoverflow.com/a/13999717/2877364](http://stackoverflow.com/a/13999717/2877364) by\n[turningtaxis](http://stackoverflow.com/users/1922919/turningtaxis)\nand on [http://stackoverflow.com/a/3960071/2877364](http://stackoverflow.com/a/3960071/2877364) by\n[ruel](http://stackoverflow.com/users/459338/ruel).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcxw42%2Fls0","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcxw42%2Fls0","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcxw42%2Fls0/lists"}