Reputation: 71
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
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
Reputation: 2737
If you want to list files that also start with . use:
for file in "${dir}/"* "${dir}/"/.[!.]* "${dir}/"/..?* ; do
Upvotes: 0
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
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
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