I am trying to use ls to get information about files and directories. My current command fails to properly get the name whenever a file/directory has a space.

I am using this to list all files/directories in a directory:

ls -al --time-style=+%s . | awk '{if ($7 != ".." && $7 != "." && $1 != "total") print $1"\t"$3"\t"$5"\t"$6"\t"$7}'

Say I have 3 directories in my pwd "no-spaces-dir", "some dir", "some other dir", this would be the output:

drwxr-xr-x.     testuser    4096    1349853378      no-space-dir
drwxr-xr-x.     testuser    4096    1349853387      some
drwxr-xr-x.     testuser    4096    1349853359      two

I'm going to say this is an issue with my awk part. So $7 should be the directory name, and obviously I could just add $8 and $9 to get my desired output for the example I set up, but I may not always know a directory will only have 1 or 2 spaces..

How can I keep this other information present (file/directory permissions, user, space, timestamp) and also get the full name in the command's output?


2 Answers 2


The problem is that awk is parsing the input with white space as field separators. This makes for trouble when you have whitespace as part of a field.

Instead of parsing the output of ls, you can use stat(1) to get what you want along with the "dotglob" bash shell option.

shopt -s dotglob  # Enable * to match files starting with a dot
stat -c $'%A\t%U\t%s\t%Y\t%n' *

The format string outputs the fields you wanted in the format you wanted. The use of $'...' allows the \t to be expanded to a tab. You could insert an actual tab character and drop the leading $ if you wanted.

Read the bash(1) man page for details on dotglob, and pay attention to GLOBIGNORE. Read the stat(1) man page for what you can put in a format string.

  • This works wonderfully! I wasn't aware of stat. I like the ability to specify other parameters or a parameter in a different format like that. The GLIBIGNORE info was also useful. Thanks!
    – Rich
    Oct 10, 2012 at 8:28

As already mentioned, parsing ls is not the best way to print the content of directory. You problem can be easily solved, however.

As file/directory name is always last column (or columns), instead of printing $7, you can print from $7 to last column. You can do this with:

substr($0, index($0, $7))

So your full command would be:

ls -al --time-style=+%s . | awk '{if ($7 != ".." && $7 != "." && $1 != "total") print $1"\t"$3"\t"$5"\t"$6"\t" substr($0,index($0,$7));}'

Also note that checking if $1 != "total" is not really good idea since it won't work on localized systems (where total may be other word). I suggest using NF>6 to ensure you have enough columns.

  • To eliminate the total line, skip line 1: … && NR != 1 Oct 10, 2012 at 22:21
  • Thanks for letting me know how to do it with my old way. I switched to use stat, but it was good for me to see a way to do it with awk. I'm still learning about things like awk, so the substr method and the NF thing was helpful.
    – Rich
    Oct 10, 2012 at 23:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.