2

How to find different files in UNIX based extension. Lets say suppose if I have 100 files for each vamsi.log-vamsi100.log, krishna.txt-krishna100.txt, super.csv..., rajat.jpeg..., kiran.xml-kiran100.xml and etc. My requirement is if I give command it'd only give how many different patterns do I have in one folder. It should also deliver one for each extension. How can I achieve this?

ls -ltr gives all files. But I need to know how many different type of files there in one folder?

3
  • What is your criterion for matching a "type"? You have three different numbering schemes in your examples (extension followed by dot followed by number, extension followed by number, and filename followed by number followed by dot followed by the extension.
    – l0b0
    Commented Nov 7, 2014 at 13:04
  • it should give result like .txt, .log, .csv one for each pattern Commented Nov 7, 2014 at 13:28
  • For answers ending in | uniq -c it might be interesting to look at the results ordered by count of files with that extension: | uniq -c | sort -n
    – Joel Purra
    Commented May 31, 2017 at 17:47

6 Answers 6

3

Bash command: for i in *; do echo "${i##*.}"; done | uniq -c

0
1

One way:

find . -maxdepth 1 -type f | sort -u -t. -k3 | wc -l

Explanation:

  • find . -maxdepth 1 -type f: find all normal files in current directory
  • sort -u -t. -k3: sort the output on 3 filed with . as a field separator and print only first of equal lines
  • wc -l: count the lines

Edit

If you are using zsh shell then you can run

echo ${(u)$(echo *(:e))} | wc -w

The result is probably better then in find case - at least multi-dot files are properly taken into account, if you are also interested in files which names start from . then

echo ${(u)$(echo {.,}*(:e))} | wc -w
3
  • Just a remark: this assumes that you don't have other dots in file names as for example a.b.c.txt.
    – jimmij
    Commented Nov 7, 2014 at 13:17
  • I'd like to offer substitute sort and wc by grep -o "\..\{,4\}$" | uniq -c
    – Costas
    Commented Nov 7, 2014 at 13:48
  • Well, one can replace sort and wc with rev | cut -d. -f1 | rev | uniq -c or even use finds exec option to directly execute awk -F"." '{print $NF}' and then pipe results to uniq -c.
    – mkalkov
    Commented Nov 7, 2014 at 14:24
1

I think a simple ls *.extension should do the trick :)

To count them, you can use ls *.extension -1 | wc -l

1
ls -1 -a | ls *.foo | wc -l

Where foo is your extension.

1
  • perhaps an explanation of the piping of the two ls commands would be useful here?
    – MattBianco
    Commented Jun 1, 2017 at 11:38
1

find . -maxdepth 1 -type f | awk -F. '{print $NF}' | sort | uniq -c

awk being used to grab whatever comes after the last . (the "extension")

sort to get all occurrences of each "extension" grouped together

uniq -c to show the number of duplicates of each row/extension.

0

Some script with bash-builtins and assotiative array

declare -A F_TYPE
unset F_TYPE
while IFS=" ," read b c d f
do
  n="$b${c:+ $c}${d:+ $d}"
  F_TYPE[$n]=$[${F_TYPE[$n]}+1]
done < <(file -b *)
for i in "${!F_TYPE[@]}"
do
  echo "$i = ${F_TYPE[$i]}"
done
echo "Totally ${#F_TYPE[@]} types"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .