How do I loop through only directories in bash?How to circumvent “Too many open files” in debianTest for link with trailing slash?How can I compress files with the output name same as parent folder?Remove Linux directories containing ONLY old filesLinux command line. Move all files and directories in directory, except some files and directoriesHow to show only hidden directories, and then find hidden files separatelyHow to batch rename files using loop combination in bash?How to read all the sub directories and create corresponding files in bash?Loop through files excluding directoriesLoop through specific set of directorieshow to use bash script to loop through two filesHow do I match only dotfiles in bash?Loop through many folders and do calculations with files with similar pattern in bash
Smoothness of finite-dimensional functional calculus
tikz: show 0 at the axis origin
Minkowski space
How can bays and straits be determined in a procedurally generated map?
Why was the small council so happy for Tyrion to become the Master of Coin?
"You are your self first supporter", a more proper way to say it
Languages that we cannot (dis)prove to be Context-Free
strToHex ( string to its hex representation as string)
Is this a crack on the carbon frame?
Maximum likelihood parameters deviate from posterior distributions
Why doesn't Newton's third law mean a person bounces back to where they started when they hit the ground?
Mage Armor with Defense fighting style (for Adventurers League bladeslinger)
How is the claim "I am in New York only if I am in America" the same as "If I am in New York, then I am in America?
Show that if two triangles built on parallel lines, with equal bases have the same perimeter only if they are congruent.
A newer friend of my brother's gave him a load of baseball cards that are supposedly extremely valuable. Is this a scam?
Why does Kotter return in Welcome Back Kotter?
"to be prejudice towards/against someone" vs "to be prejudiced against/towards someone"
What typically incentivizes a professor to change jobs to a lower ranking university?
Can I make popcorn with any corn?
To string or not to string
How do I create uniquely male characters?
In Japanese, what’s the difference between “Tonari ni” (となりに) and “Tsugi” (つぎ)? When would you use one over the other?
Is it legal for company to use my work email to pretend I still work there?
Accidentally leaked the solution to an assignment, what to do now? (I'm the prof)
How do I loop through only directories in bash?
How to circumvent “Too many open files” in debianTest for link with trailing slash?How can I compress files with the output name same as parent folder?Remove Linux directories containing ONLY old filesLinux command line. Move all files and directories in directory, except some files and directoriesHow to show only hidden directories, and then find hidden files separatelyHow to batch rename files using loop combination in bash?How to read all the sub directories and create corresponding files in bash?Loop through files excluding directoriesLoop through specific set of directorieshow to use bash script to loop through two filesHow do I match only dotfiles in bash?Loop through many folders and do calculations with files with similar pattern in bash
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have a folder with some directories and some files (some are hidden, beginning with dot).
for d in *; do
echo $d
done
will loop through all files, but I want to loop only through directories. How do I do that?
bash files directory
add a comment |
I have a folder with some directories and some files (some are hidden, beginning with dot).
for d in *; do
echo $d
done
will loop through all files, but I want to loop only through directories. How do I do that?
bash files directory
add a comment |
I have a folder with some directories and some files (some are hidden, beginning with dot).
for d in *; do
echo $d
done
will loop through all files, but I want to loop only through directories. How do I do that?
bash files directory
I have a folder with some directories and some files (some are hidden, beginning with dot).
for d in *; do
echo $d
done
will loop through all files, but I want to loop only through directories. How do I do that?
bash files directory
bash files directory
edited Oct 21 '13 at 12:13
rubo77
asked Aug 14 '13 at 15:43
rubo77rubo77
7,9022573137
7,9022573137
add a comment |
add a comment |
12 Answers
12
active
oldest
votes
You can specify a slash at the end to match only directories:
for d in */ ; do
echo "$d"
done
6
Note that it also includes symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:09
1
so how would you exclude symlinks then?
– rubo77
Aug 14 '13 at 22:55
3
@rubo77: You can test with[[ -L $d ]]
whether $d is a symbolic link.
– choroba
Aug 14 '13 at 23:00
1
@AsymLabs That's incorrect,set -P
only affects commands which change directory. sprunge.us/TNac
– Chris Down
Oct 22 '13 at 6:14
2
@choroba:[[ -L "$f" ]]
will not exclude symlinks in this case with*/
, you have to strip the trailing slash with[[ -L "$f%/" ]]
(see Test for link with trailing slash)
– rubo77
Oct 23 '13 at 6:54
|
show 7 more comments
You can test with -d
:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
This is one of the file test operators.
7
Note that it will include symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:12
17
if [[ -d "$f" && ! -L "$f" ]]
will exclude symlinks
– rubo77
Oct 22 '13 at 6:33
Will break on empty directory.if [[ "$f" = "*" ]]; then continue; fi
– Piskvor
Apr 1 at 9:02
add a comment |
Beware that choroba's solution, though elegant, can elicit unexpected behavior if no directories are available within the current directory. In this state, rather than skipping the for
loop, bash will run the loop exactly once where d
is equal to */
:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
I recommend using the following to protect against this case:
#!/usr/bin/env bash
for f in *; do
if [ -d $f ]; then
# Will not run if no directories are available
echo $f
fi
done
This code will loop through all files in the current directory, check if f
is a directory, then echo f
if the condition returns true. If f
is equal to */
, echo $f
will not execute.
1
Much easier toshopt -s nullglob
.
– choroba
Jun 23 '16 at 7:14
add a comment |
If you need to select more specific files than only directories use find
and pass it to while read
:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Use shopt -u dotglob
to exclude hidden directories (or setopt dotglob
/unsetopt dotglob
in zsh).
IFS=
to avoid splitting filenames containing one of the $IFS
, for example: 'a b'
see AsymLabs answer below for more find
options
edit:
In case you need to create an exit value from within the while loop, you can circumvent the extra subshell by this trick:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
2
I found this solution on: stackoverflow.com/a/8489394/1069083
– rubo77
Oct 22 '13 at 5:06
add a comment |
You can use pure bash for that, but it's better to use find:
find . -maxdepth 1 -type d -exec echo ;
(find additionally will include hidden directories)
8
Note that it doesn't include symlinks to directories. You can useshopt -s dotglob
forbash
to include hidden directories. Yours will also include.
. Also note that-maxdepth
is not a standard option (-prune
is).
– Stéphane Chazelas
Aug 14 '13 at 16:11
2
Thedotglob
option is interesting butdotglob
only applies to the use of*
.find .
will always include hidden directories (and the current dir as well)
– rubo77
Oct 22 '13 at 5:28
add a comment |
This is done to find both visible and hidden directories within the present working directory, excluding the root directory:
to just loop through directories:
find -path './*' -prune -type d
to include symlinks in the result:
find -L -path './*' -prune -type d
to do something to each directory (excluding symlinks):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
to exclude hidden directories:
find -path './[^.]*' -prune -type d
to execute multiple commands on the returned values (a very contrived example):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '' sh -c
"printf 'first: %-40s' ''; printf 'second: %sn' ''"
instead of 'sh -c' can also use 'bash -c', etc.
What happens if the echo '*/' in 'for d in echo */' contains, say, 60,000 directories?
– AsymLabs
Oct 21 '13 at 4:05
You will get "Too many files" error but that can be solved: How to circumvent “Too many open files” in debian
– rubo77
Oct 21 '13 at 4:09
1
The xargs example only would works for a subset of directory names 9e.g. those with spaces or newlines would not work). Better to use... -print0 | xargs -0 ...
if you don't know what the exact names are.
– Anthon
Oct 21 '13 at 4:50
1
@rubo77 added way to exclude hidden files/directories and execution of multiple commands - of course this can be done with a script too.
– AsymLabs
Oct 21 '13 at 11:22
1
I added an example in my answer at the bottom, how to do something to each directory using a function withfind * | while read file; do ...
– rubo77
Oct 22 '13 at 4:37
|
show 10 more comments
You can loop through all directories including hidden directories (beginning with a dot) in one line and multiple commands with:
for file in */ .*/ ; do echo "$file is a directory"; done
If you want to exclude symlinks:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
note: using the list */ .*/
works in bash, but also displays the folders .
and ..
while in zsh it will not show these but throw an error if there is no hidden file in the folder
A cleaner version that will include hidden directories and exclude ../ will be with the dotglob option:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
( or setopt dotglob
in zsh )
you can unset dotglob with
shopt -u dotglob
add a comment |
This will include the complete path in each directory in the list:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
1
breaks when using folders with spaces
– Alejandro Sazo
Oct 24 '16 at 2:15
add a comment |
Use find
with -exec
to loop through the directories and call a function in the exec option:
dosomething ()
echo "doing something with $1"
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' ;
Use shopt -s dotglob
or shopt -u dotglob
to include/exclude hidden directories
add a comment |
This lists all the directories together with the number of sub-directories in a given path:
for directory in */ ; do D=$(readlink -f "$directory") ; echo $D = $(find "$D" -mindepth 1 -type d | wc -l) ; done
add a comment |
ls -d */ | while read d
do
echo $d
done
This
is
one
directory
with
spaces
in
the
name
- but gets parsed as multiple.
– Piskvor
Mar 28 at 11:35
add a comment |
ls -l | grep ^d
or:
ll | grep ^d
You may set it as an alias
1
Unfortunately, I don't think this answers the question, which was "I want to loop only through directories" -- which is slightly different than thisls
-based answer, which lists directories.
– Jeff Schaller♦
Sep 11 '17 at 20:26
1
It is never a good idea to parse the output ofls
: mywiki.wooledge.org/ParsingLs
– codeforester
Aug 21 '18 at 18:38
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f86722%2fhow-do-i-loop-through-only-directories-in-bash%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
12 Answers
12
active
oldest
votes
12 Answers
12
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can specify a slash at the end to match only directories:
for d in */ ; do
echo "$d"
done
6
Note that it also includes symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:09
1
so how would you exclude symlinks then?
– rubo77
Aug 14 '13 at 22:55
3
@rubo77: You can test with[[ -L $d ]]
whether $d is a symbolic link.
– choroba
Aug 14 '13 at 23:00
1
@AsymLabs That's incorrect,set -P
only affects commands which change directory. sprunge.us/TNac
– Chris Down
Oct 22 '13 at 6:14
2
@choroba:[[ -L "$f" ]]
will not exclude symlinks in this case with*/
, you have to strip the trailing slash with[[ -L "$f%/" ]]
(see Test for link with trailing slash)
– rubo77
Oct 23 '13 at 6:54
|
show 7 more comments
You can specify a slash at the end to match only directories:
for d in */ ; do
echo "$d"
done
6
Note that it also includes symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:09
1
so how would you exclude symlinks then?
– rubo77
Aug 14 '13 at 22:55
3
@rubo77: You can test with[[ -L $d ]]
whether $d is a symbolic link.
– choroba
Aug 14 '13 at 23:00
1
@AsymLabs That's incorrect,set -P
only affects commands which change directory. sprunge.us/TNac
– Chris Down
Oct 22 '13 at 6:14
2
@choroba:[[ -L "$f" ]]
will not exclude symlinks in this case with*/
, you have to strip the trailing slash with[[ -L "$f%/" ]]
(see Test for link with trailing slash)
– rubo77
Oct 23 '13 at 6:54
|
show 7 more comments
You can specify a slash at the end to match only directories:
for d in */ ; do
echo "$d"
done
You can specify a slash at the end to match only directories:
for d in */ ; do
echo "$d"
done
edited Aug 14 '13 at 16:09
Stéphane Chazelas
313k57592948
313k57592948
answered Aug 14 '13 at 15:46
chorobachoroba
27.1k45176
27.1k45176
6
Note that it also includes symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:09
1
so how would you exclude symlinks then?
– rubo77
Aug 14 '13 at 22:55
3
@rubo77: You can test with[[ -L $d ]]
whether $d is a symbolic link.
– choroba
Aug 14 '13 at 23:00
1
@AsymLabs That's incorrect,set -P
only affects commands which change directory. sprunge.us/TNac
– Chris Down
Oct 22 '13 at 6:14
2
@choroba:[[ -L "$f" ]]
will not exclude symlinks in this case with*/
, you have to strip the trailing slash with[[ -L "$f%/" ]]
(see Test for link with trailing slash)
– rubo77
Oct 23 '13 at 6:54
|
show 7 more comments
6
Note that it also includes symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:09
1
so how would you exclude symlinks then?
– rubo77
Aug 14 '13 at 22:55
3
@rubo77: You can test with[[ -L $d ]]
whether $d is a symbolic link.
– choroba
Aug 14 '13 at 23:00
1
@AsymLabs That's incorrect,set -P
only affects commands which change directory. sprunge.us/TNac
– Chris Down
Oct 22 '13 at 6:14
2
@choroba:[[ -L "$f" ]]
will not exclude symlinks in this case with*/
, you have to strip the trailing slash with[[ -L "$f%/" ]]
(see Test for link with trailing slash)
– rubo77
Oct 23 '13 at 6:54
6
6
Note that it also includes symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:09
Note that it also includes symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:09
1
1
so how would you exclude symlinks then?
– rubo77
Aug 14 '13 at 22:55
so how would you exclude symlinks then?
– rubo77
Aug 14 '13 at 22:55
3
3
@rubo77: You can test with
[[ -L $d ]]
whether $d is a symbolic link.– choroba
Aug 14 '13 at 23:00
@rubo77: You can test with
[[ -L $d ]]
whether $d is a symbolic link.– choroba
Aug 14 '13 at 23:00
1
1
@AsymLabs That's incorrect,
set -P
only affects commands which change directory. sprunge.us/TNac– Chris Down
Oct 22 '13 at 6:14
@AsymLabs That's incorrect,
set -P
only affects commands which change directory. sprunge.us/TNac– Chris Down
Oct 22 '13 at 6:14
2
2
@choroba:
[[ -L "$f" ]]
will not exclude symlinks in this case with */
, you have to strip the trailing slash with [[ -L "$f%/" ]]
(see Test for link with trailing slash)– rubo77
Oct 23 '13 at 6:54
@choroba:
[[ -L "$f" ]]
will not exclude symlinks in this case with */
, you have to strip the trailing slash with [[ -L "$f%/" ]]
(see Test for link with trailing slash)– rubo77
Oct 23 '13 at 6:54
|
show 7 more comments
You can test with -d
:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
This is one of the file test operators.
7
Note that it will include symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:12
17
if [[ -d "$f" && ! -L "$f" ]]
will exclude symlinks
– rubo77
Oct 22 '13 at 6:33
Will break on empty directory.if [[ "$f" = "*" ]]; then continue; fi
– Piskvor
Apr 1 at 9:02
add a comment |
You can test with -d
:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
This is one of the file test operators.
7
Note that it will include symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:12
17
if [[ -d "$f" && ! -L "$f" ]]
will exclude symlinks
– rubo77
Oct 22 '13 at 6:33
Will break on empty directory.if [[ "$f" = "*" ]]; then continue; fi
– Piskvor
Apr 1 at 9:02
add a comment |
You can test with -d
:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
This is one of the file test operators.
You can test with -d
:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
This is one of the file test operators.
edited 2 days ago
answered Aug 14 '13 at 15:59
goldilocksgoldilocks
63.3k17157213
63.3k17157213
7
Note that it will include symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:12
17
if [[ -d "$f" && ! -L "$f" ]]
will exclude symlinks
– rubo77
Oct 22 '13 at 6:33
Will break on empty directory.if [[ "$f" = "*" ]]; then continue; fi
– Piskvor
Apr 1 at 9:02
add a comment |
7
Note that it will include symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:12
17
if [[ -d "$f" && ! -L "$f" ]]
will exclude symlinks
– rubo77
Oct 22 '13 at 6:33
Will break on empty directory.if [[ "$f" = "*" ]]; then continue; fi
– Piskvor
Apr 1 at 9:02
7
7
Note that it will include symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:12
Note that it will include symlinks to directories.
– Stéphane Chazelas
Aug 14 '13 at 16:12
17
17
if [[ -d "$f" && ! -L "$f" ]]
will exclude symlinks– rubo77
Oct 22 '13 at 6:33
if [[ -d "$f" && ! -L "$f" ]]
will exclude symlinks– rubo77
Oct 22 '13 at 6:33
Will break on empty directory.
if [[ "$f" = "*" ]]; then continue; fi
– Piskvor
Apr 1 at 9:02
Will break on empty directory.
if [[ "$f" = "*" ]]; then continue; fi
– Piskvor
Apr 1 at 9:02
add a comment |
Beware that choroba's solution, though elegant, can elicit unexpected behavior if no directories are available within the current directory. In this state, rather than skipping the for
loop, bash will run the loop exactly once where d
is equal to */
:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
I recommend using the following to protect against this case:
#!/usr/bin/env bash
for f in *; do
if [ -d $f ]; then
# Will not run if no directories are available
echo $f
fi
done
This code will loop through all files in the current directory, check if f
is a directory, then echo f
if the condition returns true. If f
is equal to */
, echo $f
will not execute.
1
Much easier toshopt -s nullglob
.
– choroba
Jun 23 '16 at 7:14
add a comment |
Beware that choroba's solution, though elegant, can elicit unexpected behavior if no directories are available within the current directory. In this state, rather than skipping the for
loop, bash will run the loop exactly once where d
is equal to */
:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
I recommend using the following to protect against this case:
#!/usr/bin/env bash
for f in *; do
if [ -d $f ]; then
# Will not run if no directories are available
echo $f
fi
done
This code will loop through all files in the current directory, check if f
is a directory, then echo f
if the condition returns true. If f
is equal to */
, echo $f
will not execute.
1
Much easier toshopt -s nullglob
.
– choroba
Jun 23 '16 at 7:14
add a comment |
Beware that choroba's solution, though elegant, can elicit unexpected behavior if no directories are available within the current directory. In this state, rather than skipping the for
loop, bash will run the loop exactly once where d
is equal to */
:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
I recommend using the following to protect against this case:
#!/usr/bin/env bash
for f in *; do
if [ -d $f ]; then
# Will not run if no directories are available
echo $f
fi
done
This code will loop through all files in the current directory, check if f
is a directory, then echo f
if the condition returns true. If f
is equal to */
, echo $f
will not execute.
Beware that choroba's solution, though elegant, can elicit unexpected behavior if no directories are available within the current directory. In this state, rather than skipping the for
loop, bash will run the loop exactly once where d
is equal to */
:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
I recommend using the following to protect against this case:
#!/usr/bin/env bash
for f in *; do
if [ -d $f ]; then
# Will not run if no directories are available
echo $f
fi
done
This code will loop through all files in the current directory, check if f
is a directory, then echo f
if the condition returns true. If f
is equal to */
, echo $f
will not execute.
answered Jul 26 '15 at 23:54
emagdneemagdne
34124
34124
1
Much easier toshopt -s nullglob
.
– choroba
Jun 23 '16 at 7:14
add a comment |
1
Much easier toshopt -s nullglob
.
– choroba
Jun 23 '16 at 7:14
1
1
Much easier to
shopt -s nullglob
.– choroba
Jun 23 '16 at 7:14
Much easier to
shopt -s nullglob
.– choroba
Jun 23 '16 at 7:14
add a comment |
If you need to select more specific files than only directories use find
and pass it to while read
:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Use shopt -u dotglob
to exclude hidden directories (or setopt dotglob
/unsetopt dotglob
in zsh).
IFS=
to avoid splitting filenames containing one of the $IFS
, for example: 'a b'
see AsymLabs answer below for more find
options
edit:
In case you need to create an exit value from within the while loop, you can circumvent the extra subshell by this trick:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
2
I found this solution on: stackoverflow.com/a/8489394/1069083
– rubo77
Oct 22 '13 at 5:06
add a comment |
If you need to select more specific files than only directories use find
and pass it to while read
:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Use shopt -u dotglob
to exclude hidden directories (or setopt dotglob
/unsetopt dotglob
in zsh).
IFS=
to avoid splitting filenames containing one of the $IFS
, for example: 'a b'
see AsymLabs answer below for more find
options
edit:
In case you need to create an exit value from within the while loop, you can circumvent the extra subshell by this trick:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
2
I found this solution on: stackoverflow.com/a/8489394/1069083
– rubo77
Oct 22 '13 at 5:06
add a comment |
If you need to select more specific files than only directories use find
and pass it to while read
:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Use shopt -u dotglob
to exclude hidden directories (or setopt dotglob
/unsetopt dotglob
in zsh).
IFS=
to avoid splitting filenames containing one of the $IFS
, for example: 'a b'
see AsymLabs answer below for more find
options
edit:
In case you need to create an exit value from within the while loop, you can circumvent the extra subshell by this trick:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
If you need to select more specific files than only directories use find
and pass it to while read
:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Use shopt -u dotglob
to exclude hidden directories (or setopt dotglob
/unsetopt dotglob
in zsh).
IFS=
to avoid splitting filenames containing one of the $IFS
, for example: 'a b'
see AsymLabs answer below for more find
options
edit:
In case you need to create an exit value from within the while loop, you can circumvent the extra subshell by this trick:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
edited Jul 7 '17 at 7:10
answered Oct 22 '13 at 4:50
rubo77rubo77
7,9022573137
7,9022573137
2
I found this solution on: stackoverflow.com/a/8489394/1069083
– rubo77
Oct 22 '13 at 5:06
add a comment |
2
I found this solution on: stackoverflow.com/a/8489394/1069083
– rubo77
Oct 22 '13 at 5:06
2
2
I found this solution on: stackoverflow.com/a/8489394/1069083
– rubo77
Oct 22 '13 at 5:06
I found this solution on: stackoverflow.com/a/8489394/1069083
– rubo77
Oct 22 '13 at 5:06
add a comment |
You can use pure bash for that, but it's better to use find:
find . -maxdepth 1 -type d -exec echo ;
(find additionally will include hidden directories)
8
Note that it doesn't include symlinks to directories. You can useshopt -s dotglob
forbash
to include hidden directories. Yours will also include.
. Also note that-maxdepth
is not a standard option (-prune
is).
– Stéphane Chazelas
Aug 14 '13 at 16:11
2
Thedotglob
option is interesting butdotglob
only applies to the use of*
.find .
will always include hidden directories (and the current dir as well)
– rubo77
Oct 22 '13 at 5:28
add a comment |
You can use pure bash for that, but it's better to use find:
find . -maxdepth 1 -type d -exec echo ;
(find additionally will include hidden directories)
8
Note that it doesn't include symlinks to directories. You can useshopt -s dotglob
forbash
to include hidden directories. Yours will also include.
. Also note that-maxdepth
is not a standard option (-prune
is).
– Stéphane Chazelas
Aug 14 '13 at 16:11
2
Thedotglob
option is interesting butdotglob
only applies to the use of*
.find .
will always include hidden directories (and the current dir as well)
– rubo77
Oct 22 '13 at 5:28
add a comment |
You can use pure bash for that, but it's better to use find:
find . -maxdepth 1 -type d -exec echo ;
(find additionally will include hidden directories)
You can use pure bash for that, but it's better to use find:
find . -maxdepth 1 -type d -exec echo ;
(find additionally will include hidden directories)
answered Aug 14 '13 at 15:46
rushrush
19.5k46596
19.5k46596
8
Note that it doesn't include symlinks to directories. You can useshopt -s dotglob
forbash
to include hidden directories. Yours will also include.
. Also note that-maxdepth
is not a standard option (-prune
is).
– Stéphane Chazelas
Aug 14 '13 at 16:11
2
Thedotglob
option is interesting butdotglob
only applies to the use of*
.find .
will always include hidden directories (and the current dir as well)
– rubo77
Oct 22 '13 at 5:28
add a comment |
8
Note that it doesn't include symlinks to directories. You can useshopt -s dotglob
forbash
to include hidden directories. Yours will also include.
. Also note that-maxdepth
is not a standard option (-prune
is).
– Stéphane Chazelas
Aug 14 '13 at 16:11
2
Thedotglob
option is interesting butdotglob
only applies to the use of*
.find .
will always include hidden directories (and the current dir as well)
– rubo77
Oct 22 '13 at 5:28
8
8
Note that it doesn't include symlinks to directories. You can use
shopt -s dotglob
for bash
to include hidden directories. Yours will also include .
. Also note that -maxdepth
is not a standard option (-prune
is).– Stéphane Chazelas
Aug 14 '13 at 16:11
Note that it doesn't include symlinks to directories. You can use
shopt -s dotglob
for bash
to include hidden directories. Yours will also include .
. Also note that -maxdepth
is not a standard option (-prune
is).– Stéphane Chazelas
Aug 14 '13 at 16:11
2
2
The
dotglob
option is interesting but dotglob
only applies to the use of *
. find .
will always include hidden directories (and the current dir as well)– rubo77
Oct 22 '13 at 5:28
The
dotglob
option is interesting but dotglob
only applies to the use of *
. find .
will always include hidden directories (and the current dir as well)– rubo77
Oct 22 '13 at 5:28
add a comment |
This is done to find both visible and hidden directories within the present working directory, excluding the root directory:
to just loop through directories:
find -path './*' -prune -type d
to include symlinks in the result:
find -L -path './*' -prune -type d
to do something to each directory (excluding symlinks):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
to exclude hidden directories:
find -path './[^.]*' -prune -type d
to execute multiple commands on the returned values (a very contrived example):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '' sh -c
"printf 'first: %-40s' ''; printf 'second: %sn' ''"
instead of 'sh -c' can also use 'bash -c', etc.
What happens if the echo '*/' in 'for d in echo */' contains, say, 60,000 directories?
– AsymLabs
Oct 21 '13 at 4:05
You will get "Too many files" error but that can be solved: How to circumvent “Too many open files” in debian
– rubo77
Oct 21 '13 at 4:09
1
The xargs example only would works for a subset of directory names 9e.g. those with spaces or newlines would not work). Better to use... -print0 | xargs -0 ...
if you don't know what the exact names are.
– Anthon
Oct 21 '13 at 4:50
1
@rubo77 added way to exclude hidden files/directories and execution of multiple commands - of course this can be done with a script too.
– AsymLabs
Oct 21 '13 at 11:22
1
I added an example in my answer at the bottom, how to do something to each directory using a function withfind * | while read file; do ...
– rubo77
Oct 22 '13 at 4:37
|
show 10 more comments
This is done to find both visible and hidden directories within the present working directory, excluding the root directory:
to just loop through directories:
find -path './*' -prune -type d
to include symlinks in the result:
find -L -path './*' -prune -type d
to do something to each directory (excluding symlinks):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
to exclude hidden directories:
find -path './[^.]*' -prune -type d
to execute multiple commands on the returned values (a very contrived example):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '' sh -c
"printf 'first: %-40s' ''; printf 'second: %sn' ''"
instead of 'sh -c' can also use 'bash -c', etc.
What happens if the echo '*/' in 'for d in echo */' contains, say, 60,000 directories?
– AsymLabs
Oct 21 '13 at 4:05
You will get "Too many files" error but that can be solved: How to circumvent “Too many open files” in debian
– rubo77
Oct 21 '13 at 4:09
1
The xargs example only would works for a subset of directory names 9e.g. those with spaces or newlines would not work). Better to use... -print0 | xargs -0 ...
if you don't know what the exact names are.
– Anthon
Oct 21 '13 at 4:50
1
@rubo77 added way to exclude hidden files/directories and execution of multiple commands - of course this can be done with a script too.
– AsymLabs
Oct 21 '13 at 11:22
1
I added an example in my answer at the bottom, how to do something to each directory using a function withfind * | while read file; do ...
– rubo77
Oct 22 '13 at 4:37
|
show 10 more comments
This is done to find both visible and hidden directories within the present working directory, excluding the root directory:
to just loop through directories:
find -path './*' -prune -type d
to include symlinks in the result:
find -L -path './*' -prune -type d
to do something to each directory (excluding symlinks):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
to exclude hidden directories:
find -path './[^.]*' -prune -type d
to execute multiple commands on the returned values (a very contrived example):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '' sh -c
"printf 'first: %-40s' ''; printf 'second: %sn' ''"
instead of 'sh -c' can also use 'bash -c', etc.
This is done to find both visible and hidden directories within the present working directory, excluding the root directory:
to just loop through directories:
find -path './*' -prune -type d
to include symlinks in the result:
find -L -path './*' -prune -type d
to do something to each directory (excluding symlinks):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
to exclude hidden directories:
find -path './[^.]*' -prune -type d
to execute multiple commands on the returned values (a very contrived example):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '' sh -c
"printf 'first: %-40s' ''; printf 'second: %sn' ''"
instead of 'sh -c' can also use 'bash -c', etc.
edited Oct 22 '13 at 5:11
rubo77
7,9022573137
7,9022573137
answered Oct 21 '13 at 3:47
AsymLabsAsymLabs
1,7961711
1,7961711
What happens if the echo '*/' in 'for d in echo */' contains, say, 60,000 directories?
– AsymLabs
Oct 21 '13 at 4:05
You will get "Too many files" error but that can be solved: How to circumvent “Too many open files” in debian
– rubo77
Oct 21 '13 at 4:09
1
The xargs example only would works for a subset of directory names 9e.g. those with spaces or newlines would not work). Better to use... -print0 | xargs -0 ...
if you don't know what the exact names are.
– Anthon
Oct 21 '13 at 4:50
1
@rubo77 added way to exclude hidden files/directories and execution of multiple commands - of course this can be done with a script too.
– AsymLabs
Oct 21 '13 at 11:22
1
I added an example in my answer at the bottom, how to do something to each directory using a function withfind * | while read file; do ...
– rubo77
Oct 22 '13 at 4:37
|
show 10 more comments
What happens if the echo '*/' in 'for d in echo */' contains, say, 60,000 directories?
– AsymLabs
Oct 21 '13 at 4:05
You will get "Too many files" error but that can be solved: How to circumvent “Too many open files” in debian
– rubo77
Oct 21 '13 at 4:09
1
The xargs example only would works for a subset of directory names 9e.g. those with spaces or newlines would not work). Better to use... -print0 | xargs -0 ...
if you don't know what the exact names are.
– Anthon
Oct 21 '13 at 4:50
1
@rubo77 added way to exclude hidden files/directories and execution of multiple commands - of course this can be done with a script too.
– AsymLabs
Oct 21 '13 at 11:22
1
I added an example in my answer at the bottom, how to do something to each directory using a function withfind * | while read file; do ...
– rubo77
Oct 22 '13 at 4:37
What happens if the echo '*/' in 'for d in echo */' contains, say, 60,000 directories?
– AsymLabs
Oct 21 '13 at 4:05
What happens if the echo '*/' in 'for d in echo */' contains, say, 60,000 directories?
– AsymLabs
Oct 21 '13 at 4:05
You will get "Too many files" error but that can be solved: How to circumvent “Too many open files” in debian
– rubo77
Oct 21 '13 at 4:09
You will get "Too many files" error but that can be solved: How to circumvent “Too many open files” in debian
– rubo77
Oct 21 '13 at 4:09
1
1
The xargs example only would works for a subset of directory names 9e.g. those with spaces or newlines would not work). Better to use
... -print0 | xargs -0 ...
if you don't know what the exact names are.– Anthon
Oct 21 '13 at 4:50
The xargs example only would works for a subset of directory names 9e.g. those with spaces or newlines would not work). Better to use
... -print0 | xargs -0 ...
if you don't know what the exact names are.– Anthon
Oct 21 '13 at 4:50
1
1
@rubo77 added way to exclude hidden files/directories and execution of multiple commands - of course this can be done with a script too.
– AsymLabs
Oct 21 '13 at 11:22
@rubo77 added way to exclude hidden files/directories and execution of multiple commands - of course this can be done with a script too.
– AsymLabs
Oct 21 '13 at 11:22
1
1
I added an example in my answer at the bottom, how to do something to each directory using a function with
find * | while read file; do ...
– rubo77
Oct 22 '13 at 4:37
I added an example in my answer at the bottom, how to do something to each directory using a function with
find * | while read file; do ...
– rubo77
Oct 22 '13 at 4:37
|
show 10 more comments
You can loop through all directories including hidden directories (beginning with a dot) in one line and multiple commands with:
for file in */ .*/ ; do echo "$file is a directory"; done
If you want to exclude symlinks:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
note: using the list */ .*/
works in bash, but also displays the folders .
and ..
while in zsh it will not show these but throw an error if there is no hidden file in the folder
A cleaner version that will include hidden directories and exclude ../ will be with the dotglob option:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
( or setopt dotglob
in zsh )
you can unset dotglob with
shopt -u dotglob
add a comment |
You can loop through all directories including hidden directories (beginning with a dot) in one line and multiple commands with:
for file in */ .*/ ; do echo "$file is a directory"; done
If you want to exclude symlinks:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
note: using the list */ .*/
works in bash, but also displays the folders .
and ..
while in zsh it will not show these but throw an error if there is no hidden file in the folder
A cleaner version that will include hidden directories and exclude ../ will be with the dotglob option:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
( or setopt dotglob
in zsh )
you can unset dotglob with
shopt -u dotglob
add a comment |
You can loop through all directories including hidden directories (beginning with a dot) in one line and multiple commands with:
for file in */ .*/ ; do echo "$file is a directory"; done
If you want to exclude symlinks:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
note: using the list */ .*/
works in bash, but also displays the folders .
and ..
while in zsh it will not show these but throw an error if there is no hidden file in the folder
A cleaner version that will include hidden directories and exclude ../ will be with the dotglob option:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
( or setopt dotglob
in zsh )
you can unset dotglob with
shopt -u dotglob
You can loop through all directories including hidden directories (beginning with a dot) in one line and multiple commands with:
for file in */ .*/ ; do echo "$file is a directory"; done
If you want to exclude symlinks:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
note: using the list */ .*/
works in bash, but also displays the folders .
and ..
while in zsh it will not show these but throw an error if there is no hidden file in the folder
A cleaner version that will include hidden directories and exclude ../ will be with the dotglob option:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
( or setopt dotglob
in zsh )
you can unset dotglob with
shopt -u dotglob
edited Oct 22 '13 at 4:49
community wiki
11 revs
rubo77
add a comment |
add a comment |
This will include the complete path in each directory in the list:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
1
breaks when using folders with spaces
– Alejandro Sazo
Oct 24 '16 at 2:15
add a comment |
This will include the complete path in each directory in the list:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
1
breaks when using folders with spaces
– Alejandro Sazo
Oct 24 '16 at 2:15
add a comment |
This will include the complete path in each directory in the list:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
This will include the complete path in each directory in the list:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
edited Oct 27 '13 at 23:31
rubo77
7,9022573137
7,9022573137
answered Oct 22 '13 at 5:16
user1529891user1529891
2,11562547
2,11562547
1
breaks when using folders with spaces
– Alejandro Sazo
Oct 24 '16 at 2:15
add a comment |
1
breaks when using folders with spaces
– Alejandro Sazo
Oct 24 '16 at 2:15
1
1
breaks when using folders with spaces
– Alejandro Sazo
Oct 24 '16 at 2:15
breaks when using folders with spaces
– Alejandro Sazo
Oct 24 '16 at 2:15
add a comment |
Use find
with -exec
to loop through the directories and call a function in the exec option:
dosomething ()
echo "doing something with $1"
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' ;
Use shopt -s dotglob
or shopt -u dotglob
to include/exclude hidden directories
add a comment |
Use find
with -exec
to loop through the directories and call a function in the exec option:
dosomething ()
echo "doing something with $1"
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' ;
Use shopt -s dotglob
or shopt -u dotglob
to include/exclude hidden directories
add a comment |
Use find
with -exec
to loop through the directories and call a function in the exec option:
dosomething ()
echo "doing something with $1"
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' ;
Use shopt -s dotglob
or shopt -u dotglob
to include/exclude hidden directories
Use find
with -exec
to loop through the directories and call a function in the exec option:
dosomething ()
echo "doing something with $1"
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' ;
Use shopt -s dotglob
or shopt -u dotglob
to include/exclude hidden directories
answered Oct 22 '13 at 6:26
rubo77rubo77
7,9022573137
7,9022573137
add a comment |
add a comment |
This lists all the directories together with the number of sub-directories in a given path:
for directory in */ ; do D=$(readlink -f "$directory") ; echo $D = $(find "$D" -mindepth 1 -type d | wc -l) ; done
add a comment |
This lists all the directories together with the number of sub-directories in a given path:
for directory in */ ; do D=$(readlink -f "$directory") ; echo $D = $(find "$D" -mindepth 1 -type d | wc -l) ; done
add a comment |
This lists all the directories together with the number of sub-directories in a given path:
for directory in */ ; do D=$(readlink -f "$directory") ; echo $D = $(find "$D" -mindepth 1 -type d | wc -l) ; done
This lists all the directories together with the number of sub-directories in a given path:
for directory in */ ; do D=$(readlink -f "$directory") ; echo $D = $(find "$D" -mindepth 1 -type d | wc -l) ; done
edited Dec 26 '17 at 19:44
answered Dec 26 '17 at 18:33
pabloa98pabloa98
1012
1012
add a comment |
add a comment |
ls -d */ | while read d
do
echo $d
done
This
is
one
directory
with
spaces
in
the
name
- but gets parsed as multiple.
– Piskvor
Mar 28 at 11:35
add a comment |
ls -d */ | while read d
do
echo $d
done
This
is
one
directory
with
spaces
in
the
name
- but gets parsed as multiple.
– Piskvor
Mar 28 at 11:35
add a comment |
ls -d */ | while read d
do
echo $d
done
ls -d */ | while read d
do
echo $d
done
answered Jul 27 '15 at 1:55
dcatdcat
1172
1172
This
is
one
directory
with
spaces
in
the
name
- but gets parsed as multiple.
– Piskvor
Mar 28 at 11:35
add a comment |
This
is
one
directory
with
spaces
in
the
name
- but gets parsed as multiple.
– Piskvor
Mar 28 at 11:35
This
is
one
directory
with
spaces
in
the
name
- but gets parsed as multiple.– Piskvor
Mar 28 at 11:35
This
is
one
directory
with
spaces
in
the
name
- but gets parsed as multiple.– Piskvor
Mar 28 at 11:35
add a comment |
ls -l | grep ^d
or:
ll | grep ^d
You may set it as an alias
1
Unfortunately, I don't think this answers the question, which was "I want to loop only through directories" -- which is slightly different than thisls
-based answer, which lists directories.
– Jeff Schaller♦
Sep 11 '17 at 20:26
1
It is never a good idea to parse the output ofls
: mywiki.wooledge.org/ParsingLs
– codeforester
Aug 21 '18 at 18:38
add a comment |
ls -l | grep ^d
or:
ll | grep ^d
You may set it as an alias
1
Unfortunately, I don't think this answers the question, which was "I want to loop only through directories" -- which is slightly different than thisls
-based answer, which lists directories.
– Jeff Schaller♦
Sep 11 '17 at 20:26
1
It is never a good idea to parse the output ofls
: mywiki.wooledge.org/ParsingLs
– codeforester
Aug 21 '18 at 18:38
add a comment |
ls -l | grep ^d
or:
ll | grep ^d
You may set it as an alias
ls -l | grep ^d
or:
ll | grep ^d
You may set it as an alias
edited Sep 11 '17 at 19:48
Michael Mrozek♦
62.3k29194214
62.3k29194214
answered Sep 11 '17 at 18:46
user250676user250676
1
1
1
Unfortunately, I don't think this answers the question, which was "I want to loop only through directories" -- which is slightly different than thisls
-based answer, which lists directories.
– Jeff Schaller♦
Sep 11 '17 at 20:26
1
It is never a good idea to parse the output ofls
: mywiki.wooledge.org/ParsingLs
– codeforester
Aug 21 '18 at 18:38
add a comment |
1
Unfortunately, I don't think this answers the question, which was "I want to loop only through directories" -- which is slightly different than thisls
-based answer, which lists directories.
– Jeff Schaller♦
Sep 11 '17 at 20:26
1
It is never a good idea to parse the output ofls
: mywiki.wooledge.org/ParsingLs
– codeforester
Aug 21 '18 at 18:38
1
1
Unfortunately, I don't think this answers the question, which was "I want to loop only through directories" -- which is slightly different than this
ls
-based answer, which lists directories.– Jeff Schaller♦
Sep 11 '17 at 20:26
Unfortunately, I don't think this answers the question, which was "I want to loop only through directories" -- which is slightly different than this
ls
-based answer, which lists directories.– Jeff Schaller♦
Sep 11 '17 at 20:26
1
1
It is never a good idea to parse the output of
ls
: mywiki.wooledge.org/ParsingLs– codeforester
Aug 21 '18 at 18:38
It is never a good idea to parse the output of
ls
: mywiki.wooledge.org/ParsingLs– codeforester
Aug 21 '18 at 18:38
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f86722%2fhow-do-i-loop-through-only-directories-in-bash%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown