3

I have been trying to list files in directory using ls and passing it different options.

Does it have the ability to list types of files as well ? I want to know which ones are executable , sharedlibs or just ascii files without doing file command on individual files.

1
  • old timers uses file, nowaday you can also use mimetype
    – Archemar
    Mar 22, 2015 at 9:40

2 Answers 2

3

ls itself won't show this information.

You can pipe the output of the find to file -f -, as follows:

$ find /usr/local/bin | file -f -
/usr/local/bin:              directory 
/usr/local/bin/apt:                  Python script, ASCII text executable
/usr/local/bin/mint-md5sum:                          ASCII text
/usr/local/bin/search:                     Bourne-Again shell script, ASCII text executable
/usr/local/bin/gnome-help:                         Python script, ASCII text executable
/usr/local/bin/office-vb.sh:                           ASCII text
/usr/local/bin/pastebin:                       Python script, ASCII text executable
/usr/local/bin/highlight:                        POSIX shell script, ASCII text executable
/usr/local/bin/yelp:                   Python script, ASCII text executable

Note that find is used instead of ls as it will print the full path, whereas ls will only print the file name. Therefore, if you simply need to do this with the files in your current directory, then:

ls | file -f -

would work.

2
  • i assume you meant to run file on the ls output in the last example
    – Skaperen
    Mar 22, 2015 at 10:49
  • 1
    You can use file *, file /usr/local/bin/*, etc. Piping from find is useful though if you have too many files for globbing, or want to use find's other features such as listing only recently modified files.
    – deltab
    Mar 22, 2015 at 14:00
1

ls doesn't do this. Its job is to report on file metadata (permissions, timestamp, etc.), not on file contents. But file itself does (combined with a shell wildcard to list all files):

file *

for the current directory, or

file /some/directory/*

in another directory.

If you want to combine metadata and file content information, you can combine the output of ls and file. One way is to arrange for two commands to list one file per line in the same order, and use the paste utility to combine them — something like

paste <(ls -dlog -- *) <(file -b -- *)

(This uses process substitution, which is available in common interactive shells: bash, zsh, also in ksh93.) If you have the column utility, it's a convenient way of aligning the columns:

paste <(ls -dlog -- *) <(file -b -- *) | column -ts $'\t'

If you want to output the fields in a different order, join the fields on the file name instead. I do a bit of back-and-forth between spaces and tabs to cope with file names containing spaces and produce vertically aligned results.

join -t $'\t' -1 2 -2 1 <(ls -dlog -- * |
                          sed 's/^\([^ ][^ ]*  *[^ ][^ ]*  *[^ ][^ ]*  *[^ ][^ ]*  *[^ ][^ ]*  *[^ ][^ ]*\)  */\1\t/') \
                        <(file -- * | sed 's/: */\t/') |
column -ts $'\t'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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