Count files in a directory by extension
Clash Royale CLAN TAG#URR8PPP
For the purpose of testing, I'd like count how many images files are inside a directory, separating each image file type by file extension (jpg="yes". This because later it will be useful for another script that will execute an action on each file extension). Can I use something like the following for only JPEG files?
jpg=""
count=`ls -1 *.jpg 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo jpg files found: $count ; jpg="yes"
fi
Considering file extensions jpg, png, bmp, raw and others, should I use a while
cycle to do this?
bash shell-script files wildcards
add a comment |
For the purpose of testing, I'd like count how many images files are inside a directory, separating each image file type by file extension (jpg="yes". This because later it will be useful for another script that will execute an action on each file extension). Can I use something like the following for only JPEG files?
jpg=""
count=`ls -1 *.jpg 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo jpg files found: $count ; jpg="yes"
fi
Considering file extensions jpg, png, bmp, raw and others, should I use a while
cycle to do this?
bash shell-script files wildcards
add a comment |
For the purpose of testing, I'd like count how many images files are inside a directory, separating each image file type by file extension (jpg="yes". This because later it will be useful for another script that will execute an action on each file extension). Can I use something like the following for only JPEG files?
jpg=""
count=`ls -1 *.jpg 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo jpg files found: $count ; jpg="yes"
fi
Considering file extensions jpg, png, bmp, raw and others, should I use a while
cycle to do this?
bash shell-script files wildcards
For the purpose of testing, I'd like count how many images files are inside a directory, separating each image file type by file extension (jpg="yes". This because later it will be useful for another script that will execute an action on each file extension). Can I use something like the following for only JPEG files?
jpg=""
count=`ls -1 *.jpg 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo jpg files found: $count ; jpg="yes"
fi
Considering file extensions jpg, png, bmp, raw and others, should I use a while
cycle to do this?
bash shell-script files wildcards
bash shell-script files wildcards
edited Jul 27 '14 at 19:43
Gilles
533k12810721594
533k12810721594
asked Jul 26 '14 at 19:17
watchmanskywatchmansky
2631410
2631410
add a comment |
add a comment |
7 Answers
7
active
oldest
votes
I'd suggest a different approach, avoiding the possible word-splitting issues of ls
#!/bin/bash
shopt -s nullglob
for ext in jpg png gif; do
files=( *."$ext" )
printf 'number of %s files: %dn' "$ext" "$#files[@]"
# now we can loop over all the files having the current extension
for f in "$files[@]"; do
# anything else you like with these files
done
done
You can loop over the files
array with any other commands you want to perform on the files of each particular extension.
@1_CR oops thank you - must have brace expansions on the brain! will correct above
– steeldriver
Jul 26 '14 at 21:37
add a comment |
My approach would be:
- List all files in the directory
- Extract their extension
- Sort the result
- Count the occurrences of each extension
Sort of like this (last awk
call is purely for formatting):
ls -U | awk -F . 'print $NF' | sort | uniq -c | awk 'print $2,$1'
mhmh... later should I filter each extension found for do an action for it?
– watchmansky
Jul 26 '14 at 19:24
It depends on what you want to do in the end. Can you give more information?
– groxxda
Jul 26 '14 at 19:25
My goal: a script that process each extension file (only image file) changing the size from input user data. So, I start from how many jpg files there're, next png, etc.
– watchmansky
Jul 26 '14 at 19:27
steeldrivers solution may be more appropriate then.
– groxxda
Jul 26 '14 at 19:30
1
I had bothJPG
andjpg
files, and wanted it recursively so my solution was to writefind . -type f | awk -F . 'print tolower($NF)' | sort | uniq -c | awk 'print $2,":",$1'
– Kristian
May 24 '17 at 12:40
|
show 1 more comment
This recursively traverses files and counts extensions that match:
$ find . -type f | sed -e 's/.*.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
6 tiff
7 bmp
26 jpeg
38 gif
51 jpg
54 png
add a comment |
find -type f | sed -e 's/.*.//' | sort | uniq -c
3
Don't forget a starting directory withfind
. Also, it can help future readers of these answers if you give a brief explanation of your solution (in case they would like to modify it for a slightly different case).
– Jeff Schaller
Oct 22 '15 at 16:04
How well does this solution deal with path names containing spaces? Newlines?
– dhag
Oct 22 '15 at 17:37
find
defaults to the current directory, which is how I use this. I don't think God intended filenames to have spaces in them, but this works fine for that case. If you have newlines, then you deserve all you get. I thought about an explanation but decided it would make the answer too long, I think simplicity is what matters. 99% of the cases in 1% of the time. This is probably Version 7 compatible.
– Neik
Oct 22 '15 at 21:22
add a comment |
Anything involving ls
is likely to produce unexpected results with special chars (space and other symbols). Any bashism (like arrays) isn't portable. Anything involving while read
is usually slow.
On the other hand, find
is VERY flexible (lots of options to filter), it has [at least] two syntax which are fail safe for special chars... and It scales well on large directory.
For this example, I have used -iname
to match both upper and lower case extension name. I have also restricted the -maxdepth 1
to respect your question's "in current directory". Rather than counting the number of lines, where filenames could include CR/LF, -print0
will print a NULL byte at the end of each filename... so | tr -d -c "00" | wc -l
is accurately counting files (NULL bytes!).
extensions="jpg png gif"
for ext in $extensions; do
c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "00" | wc -c)
if [ $c -gt 0 ]; then
echo "Found $c *.$ext files"
find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
# or # find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "" ";"
fi
done
P.S. -print0 | tr -d -c "00" | wc -c
can be replaced with -printf "00" | wc -c
or even -printf 'n' | wc -l
.
add a comment |
Maybe it can get shorter
exts=( *.jpg *.png *.gif ); printf "There are $#exts[@]" extensions;
add a comment |
can just use ls for something this simple IMO
ls -l /opt/ssl/certs/*.pem | wc -l
or
count=$(ls -l /some/folder/*.jpg | wc -l)
or
ls *.mp3,exe,mp4 2>/dev/null | wc -l
Why the-R
? Are you expecting that some patterns are expanded to folder names?
– Kusalananda
May 12 '18 at 6:31
Good point , was an oversight , I removed it
– Mike Q
May 12 '18 at 17:13
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%2f146760%2fcount-files-in-a-directory-by-extension%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'd suggest a different approach, avoiding the possible word-splitting issues of ls
#!/bin/bash
shopt -s nullglob
for ext in jpg png gif; do
files=( *."$ext" )
printf 'number of %s files: %dn' "$ext" "$#files[@]"
# now we can loop over all the files having the current extension
for f in "$files[@]"; do
# anything else you like with these files
done
done
You can loop over the files
array with any other commands you want to perform on the files of each particular extension.
@1_CR oops thank you - must have brace expansions on the brain! will correct above
– steeldriver
Jul 26 '14 at 21:37
add a comment |
I'd suggest a different approach, avoiding the possible word-splitting issues of ls
#!/bin/bash
shopt -s nullglob
for ext in jpg png gif; do
files=( *."$ext" )
printf 'number of %s files: %dn' "$ext" "$#files[@]"
# now we can loop over all the files having the current extension
for f in "$files[@]"; do
# anything else you like with these files
done
done
You can loop over the files
array with any other commands you want to perform on the files of each particular extension.
@1_CR oops thank you - must have brace expansions on the brain! will correct above
– steeldriver
Jul 26 '14 at 21:37
add a comment |
I'd suggest a different approach, avoiding the possible word-splitting issues of ls
#!/bin/bash
shopt -s nullglob
for ext in jpg png gif; do
files=( *."$ext" )
printf 'number of %s files: %dn' "$ext" "$#files[@]"
# now we can loop over all the files having the current extension
for f in "$files[@]"; do
# anything else you like with these files
done
done
You can loop over the files
array with any other commands you want to perform on the files of each particular extension.
I'd suggest a different approach, avoiding the possible word-splitting issues of ls
#!/bin/bash
shopt -s nullglob
for ext in jpg png gif; do
files=( *."$ext" )
printf 'number of %s files: %dn' "$ext" "$#files[@]"
# now we can loop over all the files having the current extension
for f in "$files[@]"; do
# anything else you like with these files
done
done
You can loop over the files
array with any other commands you want to perform on the files of each particular extension.
edited Jul 27 '14 at 19:42
Gilles
533k12810721594
533k12810721594
answered Jul 26 '14 at 19:29
steeldriversteeldriver
35.7k35286
35.7k35286
@1_CR oops thank you - must have brace expansions on the brain! will correct above
– steeldriver
Jul 26 '14 at 21:37
add a comment |
@1_CR oops thank you - must have brace expansions on the brain! will correct above
– steeldriver
Jul 26 '14 at 21:37
@1_CR oops thank you - must have brace expansions on the brain! will correct above
– steeldriver
Jul 26 '14 at 21:37
@1_CR oops thank you - must have brace expansions on the brain! will correct above
– steeldriver
Jul 26 '14 at 21:37
add a comment |
My approach would be:
- List all files in the directory
- Extract their extension
- Sort the result
- Count the occurrences of each extension
Sort of like this (last awk
call is purely for formatting):
ls -U | awk -F . 'print $NF' | sort | uniq -c | awk 'print $2,$1'
mhmh... later should I filter each extension found for do an action for it?
– watchmansky
Jul 26 '14 at 19:24
It depends on what you want to do in the end. Can you give more information?
– groxxda
Jul 26 '14 at 19:25
My goal: a script that process each extension file (only image file) changing the size from input user data. So, I start from how many jpg files there're, next png, etc.
– watchmansky
Jul 26 '14 at 19:27
steeldrivers solution may be more appropriate then.
– groxxda
Jul 26 '14 at 19:30
1
I had bothJPG
andjpg
files, and wanted it recursively so my solution was to writefind . -type f | awk -F . 'print tolower($NF)' | sort | uniq -c | awk 'print $2,":",$1'
– Kristian
May 24 '17 at 12:40
|
show 1 more comment
My approach would be:
- List all files in the directory
- Extract their extension
- Sort the result
- Count the occurrences of each extension
Sort of like this (last awk
call is purely for formatting):
ls -U | awk -F . 'print $NF' | sort | uniq -c | awk 'print $2,$1'
mhmh... later should I filter each extension found for do an action for it?
– watchmansky
Jul 26 '14 at 19:24
It depends on what you want to do in the end. Can you give more information?
– groxxda
Jul 26 '14 at 19:25
My goal: a script that process each extension file (only image file) changing the size from input user data. So, I start from how many jpg files there're, next png, etc.
– watchmansky
Jul 26 '14 at 19:27
steeldrivers solution may be more appropriate then.
– groxxda
Jul 26 '14 at 19:30
1
I had bothJPG
andjpg
files, and wanted it recursively so my solution was to writefind . -type f | awk -F . 'print tolower($NF)' | sort | uniq -c | awk 'print $2,":",$1'
– Kristian
May 24 '17 at 12:40
|
show 1 more comment
My approach would be:
- List all files in the directory
- Extract their extension
- Sort the result
- Count the occurrences of each extension
Sort of like this (last awk
call is purely for formatting):
ls -U | awk -F . 'print $NF' | sort | uniq -c | awk 'print $2,$1'
My approach would be:
- List all files in the directory
- Extract their extension
- Sort the result
- Count the occurrences of each extension
Sort of like this (last awk
call is purely for formatting):
ls -U | awk -F . 'print $NF' | sort | uniq -c | awk 'print $2,$1'
edited Jan 11 at 0:19
Andriy Makukha
1085
1085
answered Jul 26 '14 at 19:22
groxxdagroxxda
715310
715310
mhmh... later should I filter each extension found for do an action for it?
– watchmansky
Jul 26 '14 at 19:24
It depends on what you want to do in the end. Can you give more information?
– groxxda
Jul 26 '14 at 19:25
My goal: a script that process each extension file (only image file) changing the size from input user data. So, I start from how many jpg files there're, next png, etc.
– watchmansky
Jul 26 '14 at 19:27
steeldrivers solution may be more appropriate then.
– groxxda
Jul 26 '14 at 19:30
1
I had bothJPG
andjpg
files, and wanted it recursively so my solution was to writefind . -type f | awk -F . 'print tolower($NF)' | sort | uniq -c | awk 'print $2,":",$1'
– Kristian
May 24 '17 at 12:40
|
show 1 more comment
mhmh... later should I filter each extension found for do an action for it?
– watchmansky
Jul 26 '14 at 19:24
It depends on what you want to do in the end. Can you give more information?
– groxxda
Jul 26 '14 at 19:25
My goal: a script that process each extension file (only image file) changing the size from input user data. So, I start from how many jpg files there're, next png, etc.
– watchmansky
Jul 26 '14 at 19:27
steeldrivers solution may be more appropriate then.
– groxxda
Jul 26 '14 at 19:30
1
I had bothJPG
andjpg
files, and wanted it recursively so my solution was to writefind . -type f | awk -F . 'print tolower($NF)' | sort | uniq -c | awk 'print $2,":",$1'
– Kristian
May 24 '17 at 12:40
mhmh... later should I filter each extension found for do an action for it?
– watchmansky
Jul 26 '14 at 19:24
mhmh... later should I filter each extension found for do an action for it?
– watchmansky
Jul 26 '14 at 19:24
It depends on what you want to do in the end. Can you give more information?
– groxxda
Jul 26 '14 at 19:25
It depends on what you want to do in the end. Can you give more information?
– groxxda
Jul 26 '14 at 19:25
My goal: a script that process each extension file (only image file) changing the size from input user data. So, I start from how many jpg files there're, next png, etc.
– watchmansky
Jul 26 '14 at 19:27
My goal: a script that process each extension file (only image file) changing the size from input user data. So, I start from how many jpg files there're, next png, etc.
– watchmansky
Jul 26 '14 at 19:27
steeldrivers solution may be more appropriate then.
– groxxda
Jul 26 '14 at 19:30
steeldrivers solution may be more appropriate then.
– groxxda
Jul 26 '14 at 19:30
1
1
I had both
JPG
and jpg
files, and wanted it recursively so my solution was to write find . -type f | awk -F . 'print tolower($NF)' | sort | uniq -c | awk 'print $2,":",$1'
– Kristian
May 24 '17 at 12:40
I had both
JPG
and jpg
files, and wanted it recursively so my solution was to write find . -type f | awk -F . 'print tolower($NF)' | sort | uniq -c | awk 'print $2,":",$1'
– Kristian
May 24 '17 at 12:40
|
show 1 more comment
This recursively traverses files and counts extensions that match:
$ find . -type f | sed -e 's/.*.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
6 tiff
7 bmp
26 jpeg
38 gif
51 jpg
54 png
add a comment |
This recursively traverses files and counts extensions that match:
$ find . -type f | sed -e 's/.*.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
6 tiff
7 bmp
26 jpeg
38 gif
51 jpg
54 png
add a comment |
This recursively traverses files and counts extensions that match:
$ find . -type f | sed -e 's/.*.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
6 tiff
7 bmp
26 jpeg
38 gif
51 jpg
54 png
This recursively traverses files and counts extensions that match:
$ find . -type f | sed -e 's/.*.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
6 tiff
7 bmp
26 jpeg
38 gif
51 jpg
54 png
answered Aug 15 '17 at 1:56
KitKit
19113
19113
add a comment |
add a comment |
find -type f | sed -e 's/.*.//' | sort | uniq -c
3
Don't forget a starting directory withfind
. Also, it can help future readers of these answers if you give a brief explanation of your solution (in case they would like to modify it for a slightly different case).
– Jeff Schaller
Oct 22 '15 at 16:04
How well does this solution deal with path names containing spaces? Newlines?
– dhag
Oct 22 '15 at 17:37
find
defaults to the current directory, which is how I use this. I don't think God intended filenames to have spaces in them, but this works fine for that case. If you have newlines, then you deserve all you get. I thought about an explanation but decided it would make the answer too long, I think simplicity is what matters. 99% of the cases in 1% of the time. This is probably Version 7 compatible.
– Neik
Oct 22 '15 at 21:22
add a comment |
find -type f | sed -e 's/.*.//' | sort | uniq -c
3
Don't forget a starting directory withfind
. Also, it can help future readers of these answers if you give a brief explanation of your solution (in case they would like to modify it for a slightly different case).
– Jeff Schaller
Oct 22 '15 at 16:04
How well does this solution deal with path names containing spaces? Newlines?
– dhag
Oct 22 '15 at 17:37
find
defaults to the current directory, which is how I use this. I don't think God intended filenames to have spaces in them, but this works fine for that case. If you have newlines, then you deserve all you get. I thought about an explanation but decided it would make the answer too long, I think simplicity is what matters. 99% of the cases in 1% of the time. This is probably Version 7 compatible.
– Neik
Oct 22 '15 at 21:22
add a comment |
find -type f | sed -e 's/.*.//' | sort | uniq -c
find -type f | sed -e 's/.*.//' | sort | uniq -c
answered Oct 22 '15 at 15:56
NeikNeik
411
411
3
Don't forget a starting directory withfind
. Also, it can help future readers of these answers if you give a brief explanation of your solution (in case they would like to modify it for a slightly different case).
– Jeff Schaller
Oct 22 '15 at 16:04
How well does this solution deal with path names containing spaces? Newlines?
– dhag
Oct 22 '15 at 17:37
find
defaults to the current directory, which is how I use this. I don't think God intended filenames to have spaces in them, but this works fine for that case. If you have newlines, then you deserve all you get. I thought about an explanation but decided it would make the answer too long, I think simplicity is what matters. 99% of the cases in 1% of the time. This is probably Version 7 compatible.
– Neik
Oct 22 '15 at 21:22
add a comment |
3
Don't forget a starting directory withfind
. Also, it can help future readers of these answers if you give a brief explanation of your solution (in case they would like to modify it for a slightly different case).
– Jeff Schaller
Oct 22 '15 at 16:04
How well does this solution deal with path names containing spaces? Newlines?
– dhag
Oct 22 '15 at 17:37
find
defaults to the current directory, which is how I use this. I don't think God intended filenames to have spaces in them, but this works fine for that case. If you have newlines, then you deserve all you get. I thought about an explanation but decided it would make the answer too long, I think simplicity is what matters. 99% of the cases in 1% of the time. This is probably Version 7 compatible.
– Neik
Oct 22 '15 at 21:22
3
3
Don't forget a starting directory with
find
. Also, it can help future readers of these answers if you give a brief explanation of your solution (in case they would like to modify it for a slightly different case).– Jeff Schaller
Oct 22 '15 at 16:04
Don't forget a starting directory with
find
. Also, it can help future readers of these answers if you give a brief explanation of your solution (in case they would like to modify it for a slightly different case).– Jeff Schaller
Oct 22 '15 at 16:04
How well does this solution deal with path names containing spaces? Newlines?
– dhag
Oct 22 '15 at 17:37
How well does this solution deal with path names containing spaces? Newlines?
– dhag
Oct 22 '15 at 17:37
find
defaults to the current directory, which is how I use this. I don't think God intended filenames to have spaces in them, but this works fine for that case. If you have newlines, then you deserve all you get. I thought about an explanation but decided it would make the answer too long, I think simplicity is what matters. 99% of the cases in 1% of the time. This is probably Version 7 compatible.– Neik
Oct 22 '15 at 21:22
find
defaults to the current directory, which is how I use this. I don't think God intended filenames to have spaces in them, but this works fine for that case. If you have newlines, then you deserve all you get. I thought about an explanation but decided it would make the answer too long, I think simplicity is what matters. 99% of the cases in 1% of the time. This is probably Version 7 compatible.– Neik
Oct 22 '15 at 21:22
add a comment |
Anything involving ls
is likely to produce unexpected results with special chars (space and other symbols). Any bashism (like arrays) isn't portable. Anything involving while read
is usually slow.
On the other hand, find
is VERY flexible (lots of options to filter), it has [at least] two syntax which are fail safe for special chars... and It scales well on large directory.
For this example, I have used -iname
to match both upper and lower case extension name. I have also restricted the -maxdepth 1
to respect your question's "in current directory". Rather than counting the number of lines, where filenames could include CR/LF, -print0
will print a NULL byte at the end of each filename... so | tr -d -c "00" | wc -l
is accurately counting files (NULL bytes!).
extensions="jpg png gif"
for ext in $extensions; do
c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "00" | wc -c)
if [ $c -gt 0 ]; then
echo "Found $c *.$ext files"
find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
# or # find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "" ";"
fi
done
P.S. -print0 | tr -d -c "00" | wc -c
can be replaced with -printf "00" | wc -c
or even -printf 'n' | wc -l
.
add a comment |
Anything involving ls
is likely to produce unexpected results with special chars (space and other symbols). Any bashism (like arrays) isn't portable. Anything involving while read
is usually slow.
On the other hand, find
is VERY flexible (lots of options to filter), it has [at least] two syntax which are fail safe for special chars... and It scales well on large directory.
For this example, I have used -iname
to match both upper and lower case extension name. I have also restricted the -maxdepth 1
to respect your question's "in current directory". Rather than counting the number of lines, where filenames could include CR/LF, -print0
will print a NULL byte at the end of each filename... so | tr -d -c "00" | wc -l
is accurately counting files (NULL bytes!).
extensions="jpg png gif"
for ext in $extensions; do
c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "00" | wc -c)
if [ $c -gt 0 ]; then
echo "Found $c *.$ext files"
find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
# or # find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "" ";"
fi
done
P.S. -print0 | tr -d -c "00" | wc -c
can be replaced with -printf "00" | wc -c
or even -printf 'n' | wc -l
.
add a comment |
Anything involving ls
is likely to produce unexpected results with special chars (space and other symbols). Any bashism (like arrays) isn't portable. Anything involving while read
is usually slow.
On the other hand, find
is VERY flexible (lots of options to filter), it has [at least] two syntax which are fail safe for special chars... and It scales well on large directory.
For this example, I have used -iname
to match both upper and lower case extension name. I have also restricted the -maxdepth 1
to respect your question's "in current directory". Rather than counting the number of lines, where filenames could include CR/LF, -print0
will print a NULL byte at the end of each filename... so | tr -d -c "00" | wc -l
is accurately counting files (NULL bytes!).
extensions="jpg png gif"
for ext in $extensions; do
c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "00" | wc -c)
if [ $c -gt 0 ]; then
echo "Found $c *.$ext files"
find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
# or # find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "" ";"
fi
done
P.S. -print0 | tr -d -c "00" | wc -c
can be replaced with -printf "00" | wc -c
or even -printf 'n' | wc -l
.
Anything involving ls
is likely to produce unexpected results with special chars (space and other symbols). Any bashism (like arrays) isn't portable. Anything involving while read
is usually slow.
On the other hand, find
is VERY flexible (lots of options to filter), it has [at least] two syntax which are fail safe for special chars... and It scales well on large directory.
For this example, I have used -iname
to match both upper and lower case extension name. I have also restricted the -maxdepth 1
to respect your question's "in current directory". Rather than counting the number of lines, where filenames could include CR/LF, -print0
will print a NULL byte at the end of each filename... so | tr -d -c "00" | wc -l
is accurately counting files (NULL bytes!).
extensions="jpg png gif"
for ext in $extensions; do
c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "00" | wc -c)
if [ $c -gt 0 ]; then
echo "Found $c *.$ext files"
find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
# or # find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "" ";"
fi
done
P.S. -print0 | tr -d -c "00" | wc -c
can be replaced with -printf "00" | wc -c
or even -printf 'n' | wc -l
.
answered Apr 27 '15 at 21:16
Franklin PiatFranklin Piat
1,8841828
1,8841828
add a comment |
add a comment |
Maybe it can get shorter
exts=( *.jpg *.png *.gif ); printf "There are $#exts[@]" extensions;
add a comment |
Maybe it can get shorter
exts=( *.jpg *.png *.gif ); printf "There are $#exts[@]" extensions;
add a comment |
Maybe it can get shorter
exts=( *.jpg *.png *.gif ); printf "There are $#exts[@]" extensions;
Maybe it can get shorter
exts=( *.jpg *.png *.gif ); printf "There are $#exts[@]" extensions;
answered Jul 26 '14 at 21:36
Valentin BajramiValentin Bajrami
5,97111627
5,97111627
add a comment |
add a comment |
can just use ls for something this simple IMO
ls -l /opt/ssl/certs/*.pem | wc -l
or
count=$(ls -l /some/folder/*.jpg | wc -l)
or
ls *.mp3,exe,mp4 2>/dev/null | wc -l
Why the-R
? Are you expecting that some patterns are expanded to folder names?
– Kusalananda
May 12 '18 at 6:31
Good point , was an oversight , I removed it
– Mike Q
May 12 '18 at 17:13
add a comment |
can just use ls for something this simple IMO
ls -l /opt/ssl/certs/*.pem | wc -l
or
count=$(ls -l /some/folder/*.jpg | wc -l)
or
ls *.mp3,exe,mp4 2>/dev/null | wc -l
Why the-R
? Are you expecting that some patterns are expanded to folder names?
– Kusalananda
May 12 '18 at 6:31
Good point , was an oversight , I removed it
– Mike Q
May 12 '18 at 17:13
add a comment |
can just use ls for something this simple IMO
ls -l /opt/ssl/certs/*.pem | wc -l
or
count=$(ls -l /some/folder/*.jpg | wc -l)
or
ls *.mp3,exe,mp4 2>/dev/null | wc -l
can just use ls for something this simple IMO
ls -l /opt/ssl/certs/*.pem | wc -l
or
count=$(ls -l /some/folder/*.jpg | wc -l)
or
ls *.mp3,exe,mp4 2>/dev/null | wc -l
edited May 12 '18 at 17:12
answered May 12 '18 at 2:44
Mike QMike Q
1114
1114
Why the-R
? Are you expecting that some patterns are expanded to folder names?
– Kusalananda
May 12 '18 at 6:31
Good point , was an oversight , I removed it
– Mike Q
May 12 '18 at 17:13
add a comment |
Why the-R
? Are you expecting that some patterns are expanded to folder names?
– Kusalananda
May 12 '18 at 6:31
Good point , was an oversight , I removed it
– Mike Q
May 12 '18 at 17:13
Why the
-R
? Are you expecting that some patterns are expanded to folder names?– Kusalananda
May 12 '18 at 6:31
Why the
-R
? Are you expecting that some patterns are expanded to folder names?– Kusalananda
May 12 '18 at 6:31
Good point , was an oversight , I removed it
– Mike Q
May 12 '18 at 17:13
Good point , was an oversight , I removed it
– Mike Q
May 12 '18 at 17:13
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%2f146760%2fcount-files-in-a-directory-by-extension%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