Find directories that do not contain subdirectories
I'm writing script is ksh. Need to find all directory names directly under the current directory which contain only files, not subdirectories.
I know that I could use ls -alR
and recursively parse output for the first letter in the first field (d
for a directory). I think awk
is the best way to parse and find.
For example, a simple ls -al
output in the current directory:
drwxr-xr-x 22 af staff 748 18 Mar 22:21 .
drwxr-xr-x 5 root admin 170 17 Mar 18:03 ..
-rw------- 1 af staff 3 17 Mar 16:37 .CFUserTextEncoding
drwxr-xr-x 5 af staff 170 17 Mar 17:12 Public
drwxr-xr-x 9 af staff 306 18 Mar 17:40 Sites
-rw------- 1 af staff 3 17 Mar 16:37 textd
…
There are 2 directories in this output: Public
and Sites
. The directory Public
doesn't contain subdirectories, but Sites
does. There are 3 subdirectories in Sites
. So I need to echo only the directories which don't contain directories in them. In my case, this is only Sites
.
shell find directory ls ksh
add a comment |
I'm writing script is ksh. Need to find all directory names directly under the current directory which contain only files, not subdirectories.
I know that I could use ls -alR
and recursively parse output for the first letter in the first field (d
for a directory). I think awk
is the best way to parse and find.
For example, a simple ls -al
output in the current directory:
drwxr-xr-x 22 af staff 748 18 Mar 22:21 .
drwxr-xr-x 5 root admin 170 17 Mar 18:03 ..
-rw------- 1 af staff 3 17 Mar 16:37 .CFUserTextEncoding
drwxr-xr-x 5 af staff 170 17 Mar 17:12 Public
drwxr-xr-x 9 af staff 306 18 Mar 17:40 Sites
-rw------- 1 af staff 3 17 Mar 16:37 textd
…
There are 2 directories in this output: Public
and Sites
. The directory Public
doesn't contain subdirectories, but Sites
does. There are 3 subdirectories in Sites
. So I need to echo only the directories which don't contain directories in them. In my case, this is only Sites
.
shell find directory ls ksh
add a comment |
I'm writing script is ksh. Need to find all directory names directly under the current directory which contain only files, not subdirectories.
I know that I could use ls -alR
and recursively parse output for the first letter in the first field (d
for a directory). I think awk
is the best way to parse and find.
For example, a simple ls -al
output in the current directory:
drwxr-xr-x 22 af staff 748 18 Mar 22:21 .
drwxr-xr-x 5 root admin 170 17 Mar 18:03 ..
-rw------- 1 af staff 3 17 Mar 16:37 .CFUserTextEncoding
drwxr-xr-x 5 af staff 170 17 Mar 17:12 Public
drwxr-xr-x 9 af staff 306 18 Mar 17:40 Sites
-rw------- 1 af staff 3 17 Mar 16:37 textd
…
There are 2 directories in this output: Public
and Sites
. The directory Public
doesn't contain subdirectories, but Sites
does. There are 3 subdirectories in Sites
. So I need to echo only the directories which don't contain directories in them. In my case, this is only Sites
.
shell find directory ls ksh
I'm writing script is ksh. Need to find all directory names directly under the current directory which contain only files, not subdirectories.
I know that I could use ls -alR
and recursively parse output for the first letter in the first field (d
for a directory). I think awk
is the best way to parse and find.
For example, a simple ls -al
output in the current directory:
drwxr-xr-x 22 af staff 748 18 Mar 22:21 .
drwxr-xr-x 5 root admin 170 17 Mar 18:03 ..
-rw------- 1 af staff 3 17 Mar 16:37 .CFUserTextEncoding
drwxr-xr-x 5 af staff 170 17 Mar 17:12 Public
drwxr-xr-x 9 af staff 306 18 Mar 17:40 Sites
-rw------- 1 af staff 3 17 Mar 16:37 textd
…
There are 2 directories in this output: Public
and Sites
. The directory Public
doesn't contain subdirectories, but Sites
does. There are 3 subdirectories in Sites
. So I need to echo only the directories which don't contain directories in them. In my case, this is only Sites
.
shell find directory ls ksh
shell find directory ls ksh
edited Nov 21 '18 at 22:03
Rui F Ribeiro
39.9k1479135
39.9k1479135
asked Mar 20 '13 at 16:31
Nat KupNat Kup
3314
3314
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
You don't need to use awk
at all. Use the built-in tests that ksh
provides, something like this:
#!/bin/ksh
for NAME in *
do
FOUND=no
if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
then
for SUBNAME in $NAME/*
do
if [[ -d $SUBNAME ]]
then
FOUND=yes
break
fi
done
if [[ $FOUND == no ]]
then
echo Found only files in $NAME
fi
fi
done
That little script looks in all the directories in the current directory, and tells you if they only contain files, no sub-directories.
add a comment |
If you are able to use find
and if you are working on a "normal Unix filesystem" (that is, as defined in find(1) under -noleaf option description), then the following command can be used:
find . -type d -links 2
Each directory has at least 2 names (hard links): .
and its name. Its subdirectories, if any, will have a ..
pointing to the parent directory, so a directory with N subdirectories will have hard link count equal to N+2. Thus, searching for directories with hard link count equal to 2, we search for directories with N=0 subdirectories.
So, if you can use find
, this is arguably the fastest method and obviously superior to in-shell loops over the directory contents stat()
'ing each of its members.
This doesn't seem to work if the directory contains any files.
– user394
Sep 26 '18 at 0:58
1
It's not about entries in the directory listing, it's about hard links referring to the directory's inode. For example, if/some/directory
has inode #12345678, if it has no sub-directories, there will be exactly 2 hard links to that inode:/some/directory/.
and/some/directory
. It works whether or not there are any files in the directory.
– telcoM
Jan 28 at 13:05
Worth mentioning that BTRFS is not a "normal Unix filesystem" in this respect: directories always have a link count of 1, unfortunately. (But.
andfoo/..
do have the same inode number.)
– Peter Cordes
Jan 29 at 5:04
add a comment |
*/
matches the subdirectories of the current directory. This includes symbolic links to directories, which you may or may not desire.
In ksh93, adding ~(N)
at the beginning of the pattern makes it expand to the empty list if there is no match. Without this, the pattern remains unchanged if there is no match.
The following ksh93 function lists the subdirectories of the current directories that do not contain any subdirectory or link to a directory.
list_leaf_directories () {
local FIGNORE='.?(.)' # don't ignore dot files
local d
for d in */; do
[[ -L $d ]] || continue; # skip symbolic links
set -- ~(N)"$d"/*/
if ((!$#)); then echo "$d"; fi
done
done
add a comment |
if I am not misunderstanding you, you only want to find files in the directory not the subdirectories. If this is your intention, here is the solution
find . -type f
if you want to find other than regular files (like block device files, character device files etc) then see the man page for find
command and look for the type keyword on that page. You will see different filetypes, including regular files and directories etc.
Hope this is what you are looking for
No, that's not the question at all. It's reasonably clear once you s/catalogue/directory/g. Nat Kup is looking for directories that don't contain subdirectories.
– Gilles
Mar 20 '13 at 23:12
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%2f68577%2ffind-directories-that-do-not-contain-subdirectories%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You don't need to use awk
at all. Use the built-in tests that ksh
provides, something like this:
#!/bin/ksh
for NAME in *
do
FOUND=no
if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
then
for SUBNAME in $NAME/*
do
if [[ -d $SUBNAME ]]
then
FOUND=yes
break
fi
done
if [[ $FOUND == no ]]
then
echo Found only files in $NAME
fi
fi
done
That little script looks in all the directories in the current directory, and tells you if they only contain files, no sub-directories.
add a comment |
You don't need to use awk
at all. Use the built-in tests that ksh
provides, something like this:
#!/bin/ksh
for NAME in *
do
FOUND=no
if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
then
for SUBNAME in $NAME/*
do
if [[ -d $SUBNAME ]]
then
FOUND=yes
break
fi
done
if [[ $FOUND == no ]]
then
echo Found only files in $NAME
fi
fi
done
That little script looks in all the directories in the current directory, and tells you if they only contain files, no sub-directories.
add a comment |
You don't need to use awk
at all. Use the built-in tests that ksh
provides, something like this:
#!/bin/ksh
for NAME in *
do
FOUND=no
if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
then
for SUBNAME in $NAME/*
do
if [[ -d $SUBNAME ]]
then
FOUND=yes
break
fi
done
if [[ $FOUND == no ]]
then
echo Found only files in $NAME
fi
fi
done
That little script looks in all the directories in the current directory, and tells you if they only contain files, no sub-directories.
You don't need to use awk
at all. Use the built-in tests that ksh
provides, something like this:
#!/bin/ksh
for NAME in *
do
FOUND=no
if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
then
for SUBNAME in $NAME/*
do
if [[ -d $SUBNAME ]]
then
FOUND=yes
break
fi
done
if [[ $FOUND == no ]]
then
echo Found only files in $NAME
fi
fi
done
That little script looks in all the directories in the current directory, and tells you if they only contain files, no sub-directories.
answered Mar 20 '13 at 16:44
Bruce EdigerBruce Ediger
35k566119
35k566119
add a comment |
add a comment |
If you are able to use find
and if you are working on a "normal Unix filesystem" (that is, as defined in find(1) under -noleaf option description), then the following command can be used:
find . -type d -links 2
Each directory has at least 2 names (hard links): .
and its name. Its subdirectories, if any, will have a ..
pointing to the parent directory, so a directory with N subdirectories will have hard link count equal to N+2. Thus, searching for directories with hard link count equal to 2, we search for directories with N=0 subdirectories.
So, if you can use find
, this is arguably the fastest method and obviously superior to in-shell loops over the directory contents stat()
'ing each of its members.
This doesn't seem to work if the directory contains any files.
– user394
Sep 26 '18 at 0:58
1
It's not about entries in the directory listing, it's about hard links referring to the directory's inode. For example, if/some/directory
has inode #12345678, if it has no sub-directories, there will be exactly 2 hard links to that inode:/some/directory/.
and/some/directory
. It works whether or not there are any files in the directory.
– telcoM
Jan 28 at 13:05
Worth mentioning that BTRFS is not a "normal Unix filesystem" in this respect: directories always have a link count of 1, unfortunately. (But.
andfoo/..
do have the same inode number.)
– Peter Cordes
Jan 29 at 5:04
add a comment |
If you are able to use find
and if you are working on a "normal Unix filesystem" (that is, as defined in find(1) under -noleaf option description), then the following command can be used:
find . -type d -links 2
Each directory has at least 2 names (hard links): .
and its name. Its subdirectories, if any, will have a ..
pointing to the parent directory, so a directory with N subdirectories will have hard link count equal to N+2. Thus, searching for directories with hard link count equal to 2, we search for directories with N=0 subdirectories.
So, if you can use find
, this is arguably the fastest method and obviously superior to in-shell loops over the directory contents stat()
'ing each of its members.
This doesn't seem to work if the directory contains any files.
– user394
Sep 26 '18 at 0:58
1
It's not about entries in the directory listing, it's about hard links referring to the directory's inode. For example, if/some/directory
has inode #12345678, if it has no sub-directories, there will be exactly 2 hard links to that inode:/some/directory/.
and/some/directory
. It works whether or not there are any files in the directory.
– telcoM
Jan 28 at 13:05
Worth mentioning that BTRFS is not a "normal Unix filesystem" in this respect: directories always have a link count of 1, unfortunately. (But.
andfoo/..
do have the same inode number.)
– Peter Cordes
Jan 29 at 5:04
add a comment |
If you are able to use find
and if you are working on a "normal Unix filesystem" (that is, as defined in find(1) under -noleaf option description), then the following command can be used:
find . -type d -links 2
Each directory has at least 2 names (hard links): .
and its name. Its subdirectories, if any, will have a ..
pointing to the parent directory, so a directory with N subdirectories will have hard link count equal to N+2. Thus, searching for directories with hard link count equal to 2, we search for directories with N=0 subdirectories.
So, if you can use find
, this is arguably the fastest method and obviously superior to in-shell loops over the directory contents stat()
'ing each of its members.
If you are able to use find
and if you are working on a "normal Unix filesystem" (that is, as defined in find(1) under -noleaf option description), then the following command can be used:
find . -type d -links 2
Each directory has at least 2 names (hard links): .
and its name. Its subdirectories, if any, will have a ..
pointing to the parent directory, so a directory with N subdirectories will have hard link count equal to N+2. Thus, searching for directories with hard link count equal to 2, we search for directories with N=0 subdirectories.
So, if you can use find
, this is arguably the fastest method and obviously superior to in-shell loops over the directory contents stat()
'ing each of its members.
answered May 18 '15 at 3:28
intelfxintelfx
3,0991227
3,0991227
This doesn't seem to work if the directory contains any files.
– user394
Sep 26 '18 at 0:58
1
It's not about entries in the directory listing, it's about hard links referring to the directory's inode. For example, if/some/directory
has inode #12345678, if it has no sub-directories, there will be exactly 2 hard links to that inode:/some/directory/.
and/some/directory
. It works whether or not there are any files in the directory.
– telcoM
Jan 28 at 13:05
Worth mentioning that BTRFS is not a "normal Unix filesystem" in this respect: directories always have a link count of 1, unfortunately. (But.
andfoo/..
do have the same inode number.)
– Peter Cordes
Jan 29 at 5:04
add a comment |
This doesn't seem to work if the directory contains any files.
– user394
Sep 26 '18 at 0:58
1
It's not about entries in the directory listing, it's about hard links referring to the directory's inode. For example, if/some/directory
has inode #12345678, if it has no sub-directories, there will be exactly 2 hard links to that inode:/some/directory/.
and/some/directory
. It works whether or not there are any files in the directory.
– telcoM
Jan 28 at 13:05
Worth mentioning that BTRFS is not a "normal Unix filesystem" in this respect: directories always have a link count of 1, unfortunately. (But.
andfoo/..
do have the same inode number.)
– Peter Cordes
Jan 29 at 5:04
This doesn't seem to work if the directory contains any files.
– user394
Sep 26 '18 at 0:58
This doesn't seem to work if the directory contains any files.
– user394
Sep 26 '18 at 0:58
1
1
It's not about entries in the directory listing, it's about hard links referring to the directory's inode. For example, if
/some/directory
has inode #12345678, if it has no sub-directories, there will be exactly 2 hard links to that inode: /some/directory/.
and /some/directory
. It works whether or not there are any files in the directory.– telcoM
Jan 28 at 13:05
It's not about entries in the directory listing, it's about hard links referring to the directory's inode. For example, if
/some/directory
has inode #12345678, if it has no sub-directories, there will be exactly 2 hard links to that inode: /some/directory/.
and /some/directory
. It works whether or not there are any files in the directory.– telcoM
Jan 28 at 13:05
Worth mentioning that BTRFS is not a "normal Unix filesystem" in this respect: directories always have a link count of 1, unfortunately. (But
.
and foo/..
do have the same inode number.)– Peter Cordes
Jan 29 at 5:04
Worth mentioning that BTRFS is not a "normal Unix filesystem" in this respect: directories always have a link count of 1, unfortunately. (But
.
and foo/..
do have the same inode number.)– Peter Cordes
Jan 29 at 5:04
add a comment |
*/
matches the subdirectories of the current directory. This includes symbolic links to directories, which you may or may not desire.
In ksh93, adding ~(N)
at the beginning of the pattern makes it expand to the empty list if there is no match. Without this, the pattern remains unchanged if there is no match.
The following ksh93 function lists the subdirectories of the current directories that do not contain any subdirectory or link to a directory.
list_leaf_directories () {
local FIGNORE='.?(.)' # don't ignore dot files
local d
for d in */; do
[[ -L $d ]] || continue; # skip symbolic links
set -- ~(N)"$d"/*/
if ((!$#)); then echo "$d"; fi
done
done
add a comment |
*/
matches the subdirectories of the current directory. This includes symbolic links to directories, which you may or may not desire.
In ksh93, adding ~(N)
at the beginning of the pattern makes it expand to the empty list if there is no match. Without this, the pattern remains unchanged if there is no match.
The following ksh93 function lists the subdirectories of the current directories that do not contain any subdirectory or link to a directory.
list_leaf_directories () {
local FIGNORE='.?(.)' # don't ignore dot files
local d
for d in */; do
[[ -L $d ]] || continue; # skip symbolic links
set -- ~(N)"$d"/*/
if ((!$#)); then echo "$d"; fi
done
done
add a comment |
*/
matches the subdirectories of the current directory. This includes symbolic links to directories, which you may or may not desire.
In ksh93, adding ~(N)
at the beginning of the pattern makes it expand to the empty list if there is no match. Without this, the pattern remains unchanged if there is no match.
The following ksh93 function lists the subdirectories of the current directories that do not contain any subdirectory or link to a directory.
list_leaf_directories () {
local FIGNORE='.?(.)' # don't ignore dot files
local d
for d in */; do
[[ -L $d ]] || continue; # skip symbolic links
set -- ~(N)"$d"/*/
if ((!$#)); then echo "$d"; fi
done
done
*/
matches the subdirectories of the current directory. This includes symbolic links to directories, which you may or may not desire.
In ksh93, adding ~(N)
at the beginning of the pattern makes it expand to the empty list if there is no match. Without this, the pattern remains unchanged if there is no match.
The following ksh93 function lists the subdirectories of the current directories that do not contain any subdirectory or link to a directory.
list_leaf_directories () {
local FIGNORE='.?(.)' # don't ignore dot files
local d
for d in */; do
[[ -L $d ]] || continue; # skip symbolic links
set -- ~(N)"$d"/*/
if ((!$#)); then echo "$d"; fi
done
done
edited Jan 28 at 17:38
Stéphane Chazelas
304k57573927
304k57573927
answered Mar 21 '13 at 1:01
GillesGilles
535k12810821599
535k12810821599
add a comment |
add a comment |
if I am not misunderstanding you, you only want to find files in the directory not the subdirectories. If this is your intention, here is the solution
find . -type f
if you want to find other than regular files (like block device files, character device files etc) then see the man page for find
command and look for the type keyword on that page. You will see different filetypes, including regular files and directories etc.
Hope this is what you are looking for
No, that's not the question at all. It's reasonably clear once you s/catalogue/directory/g. Nat Kup is looking for directories that don't contain subdirectories.
– Gilles
Mar 20 '13 at 23:12
add a comment |
if I am not misunderstanding you, you only want to find files in the directory not the subdirectories. If this is your intention, here is the solution
find . -type f
if you want to find other than regular files (like block device files, character device files etc) then see the man page for find
command and look for the type keyword on that page. You will see different filetypes, including regular files and directories etc.
Hope this is what you are looking for
No, that's not the question at all. It's reasonably clear once you s/catalogue/directory/g. Nat Kup is looking for directories that don't contain subdirectories.
– Gilles
Mar 20 '13 at 23:12
add a comment |
if I am not misunderstanding you, you only want to find files in the directory not the subdirectories. If this is your intention, here is the solution
find . -type f
if you want to find other than regular files (like block device files, character device files etc) then see the man page for find
command and look for the type keyword on that page. You will see different filetypes, including regular files and directories etc.
Hope this is what you are looking for
if I am not misunderstanding you, you only want to find files in the directory not the subdirectories. If this is your intention, here is the solution
find . -type f
if you want to find other than regular files (like block device files, character device files etc) then see the man page for find
command and look for the type keyword on that page. You will see different filetypes, including regular files and directories etc.
Hope this is what you are looking for
answered Mar 20 '13 at 16:44
MelBurslanMelBurslan
5,30011533
5,30011533
No, that's not the question at all. It's reasonably clear once you s/catalogue/directory/g. Nat Kup is looking for directories that don't contain subdirectories.
– Gilles
Mar 20 '13 at 23:12
add a comment |
No, that's not the question at all. It's reasonably clear once you s/catalogue/directory/g. Nat Kup is looking for directories that don't contain subdirectories.
– Gilles
Mar 20 '13 at 23:12
No, that's not the question at all. It's reasonably clear once you s/catalogue/directory/g. Nat Kup is looking for directories that don't contain subdirectories.
– Gilles
Mar 20 '13 at 23:12
No, that's not the question at all. It's reasonably clear once you s/catalogue/directory/g. Nat Kup is looking for directories that don't contain subdirectories.
– Gilles
Mar 20 '13 at 23:12
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%2f68577%2ffind-directories-that-do-not-contain-subdirectories%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