Is it possible to list only the filename and size for each file in a directory using only options found in the ls utility?

Suppose my directory, Historic_Documents has the following files/sizes:

  • Declaration_of_Independence.txt 342 bytes
  • Magna_Carta.txt 1580 bytes
  • Treaty_of_Versaille.txt 752 bytes.

Is it possible using only the ls command to get following output?

342 Declaration_of_Independence.txt
1580 Magna_Carta.txt
752 Treaty_of_Versaille.txt

How to parse output from ls -l verbose listing with a while loop:
I looked at this question and thought OK this is something you can do fairly easily with find:

$ find -maxdepth 1 -type f -printf '%s %f\n'

Or

#!/bin/bash
for i in *; do
    stat --format '%s %N' "$i"
done

(%N will honor QUOTING_STYLE environment variable; default is 'shell-escape').

Only way to get size from ls is through verbose listing. By using read to read ls output; leading and trailing spaces will be removed from the word before assigned to a variable, the first word is assigned to the first variable and so on, when all variables are assigned, the remaining words will be added to the last variable, that way we can preserve spaces on the filename.

#!/bin/bash
while read -r p c u g s e n; do
    [[ $p = total ]] && continue || { echo -n "$s "; eval "ls -d $n"; }
done < <(ls -Lpl --time-style=+%s --quoting-style=shell-escape)

(using echo -n "$s "; eval "ls -d $n" is a bit excessive, but it shows how to use 'shell-escape' with other commands. If you just want to show the output for size and name, use echo "$s $n" instead)

read variables:

-rwxr-xr-x 1 bac0n bac0n 209 1572207800 script.sh
     ^     ^   ^     ^    ^      ^         ^
     p     c   u     g    s      e         n

ls options:

  • -L when showing file information for a symbolic link, show information for the file the link references rather than for the link itself.
  • -p append / indicator to directories.
  • -l use a long listing format.
  • --time-style time/date format with -l; its a good practice to set this to epoch in scripts.
  • --quoting-style quoting non-printable characters using the POSIX proposed ‘$''’ syntax.

test directory:

$ ls
a  'b'$'\r''c'   'd'$'\n''e'  "f'g"   h,i  'j k'  'l  m'  'n  '  '  o'

Using only the ls options, you can do this:

ls -sd --block-size=1 --format=single-column *

Here are the options:

  • -sd says to print the allocated file size in blocks and the d option removes the directory "total" line from the output

  • --block-size=1 prints 1 byte per size unit (instead of K)

  • --format=single-column says to print the results as a single column

  • * says to run ls on all files in the current directory and is needed when using the d option

This assumes your current directory is Historic_Documents.


EDIT:

Because you want the size of the file contents, I don't think you can do this with only ls options. However, you can use du to get the exact result you desire:

du -b *

The -b or --bytes option prints the actual file size in bytes which is also equivalent to the options: --apparent-size --block-size=1.

Apparent size is the size of the file (the similar to the sizes listed by ls -l) and not the allocated file size or disk usage.


With just ls, no, but with stat (if you have ls you have stat):

stat -c "%s %n" *
  • stat with a format (-c, --format) is the most flexible way to obtain file data
  • Although not explicitly stated in the man page, you can use width & precision specifiers on the fields, for instance to have the size listed on 8 columns:

    stat -c "%8s %n" *
    

It's impossible to do with the ls command by itself. You can do it by piping ls -l output to other commands or with a totally different command like find as others have answered.

The tree command gives another alternative:

rick@alien:~/askubuntu$ tree -h
.
├── [8.8K]  aptfielout
├── [1.8K]  aptfilein
├── [ 435]  aptfileout
   (... SNIP ...)
├── [  38]  script
├── [4.0K]  subdir-A
│   ├── [  14]  1.mp4
│   ├── [  14]  2.mp4
│   ├── [  14]  3.mp4
│   └── [4.0K]  JSON
│       └── [4.0K]  JSON
│           ├── [   7]  1.json
│           ├── [   7]  2.json
│           ├── [   7]  3.json
│           └── [   7]  4.json
   (... SNIP ...)
├── [1.5K]  ttlus
└── [1.3K]  ttlus~

7 directories, 57 files

The tree option passed is -h for human readable size. For size in exact bytes pass -s.