Ant695
Ant695

Reputation: 71

Shell Script to list files in a given directory and if they are files or directories

Currently learning some bash scripting and having an issue with a question involving listing all files in a given directory and stating if they are a file or directory. The issue I am having is that I only get either my current directory or if a specify a directory it will just say that it is a directory eg. /home/user/shell_scripts will return shell_scipts is a directory rather than the files contained within it. This is what I have so far:

dir=$dir
for file in $dir; do
    if [[ -d $file ]]; then
        echo "$file is a directory"
    if [[ -f $file ]]; then
        echo "$file is a regular file"
    fi
done

Upvotes: 3

Views: 48667

Answers (5)

agc
agc

Reputation: 8406

ls -F ~ | \
sed 's#.*/$#/& is a Directory#;t quit;s#.*#/& is a File#;:quit;s/[*/=>@|] / /'

The -F "classify" switch appends a "/" if a file is a directory. The sed code prints the desired message, then removes the suffix.

Upvotes: 2

TrevTheDev
TrevTheDev

Reputation: 2737

If you want to list files that also start with . use:

for file in "${dir}/"* "${dir}/"/.[!.]* "${dir}/"/..?* ; do

Upvotes: 0

Component 10
Component 10

Reputation: 10467

Your line:

for file in $dir; do

will expand $dir just to a single directory string. What you need to do is expand that to a list of files in the directory. You could do this using the following:

for file in "${dir}/"* ; do

This will expand the "${dir}/"* section into a name-only list of the current directory. As Biffen points out, this should guarantee that the file list wont end up with split partial file names in file if any of them contain whitespace.

If you want to recurse into the directories in dir then using find might be a better approach. Simply use:

for file in $( find ${dir} ); do

Note that while simple, this will not handle files or directories with spaces in them. Because of this, I would be tempted to drop the loop and generate the output in one go. This might be slightly different than what you want, but is likely to be easier to read and a lot more efficient, especially with large numbers of files. For example, To list all the directories:

find ${dir} -maxdepth 1 -type d

and to list the files:

find ${dir} -maxdepth 1 -type f

if you want to iterate into directories below, then remove the -maxdepth 1

Upvotes: 8

Biffen
Biffen

Reputation: 6357

This is a good use for globbing:

for file in "$dir/"*
do
  [[ -d "$file" ]] && echo "$file is a directory"
  [[ -f "$file" ]] && echo "$file is a regular file"
done

This will work even if files in $dir have special characters in their names, such as spaces, asterisks and even newlines.

Also note that variables should be quoted ("$file"). But * must not be quoted. And I removed dir=$dir since it doesn't do anything (except break when $dir contains special characters).

Upvotes: 2

Enjoy Red
Enjoy Red

Reputation: 9

for file in $(ls $dir)
do
    [ -f $file ] && echo "$file is File"
    [ -d $file ] && echo "$file is Directory"
done

or replace the

$(ls $dir)

with

`ls $`

Upvotes: 0

Related Questions