du which counts number of files/directories rather than size

708

Solution 1

The following PHP script does the trick.

#!/usr/bin/php
<?php 

function do_scan($dir, $dev) {
  $total = 1;

  if (\filetype($dir) === 'dir' && \lstat($dir)['dev'] == $dev) {
    foreach (\scandir($dir) as $file) {
      if ($file !== '.' && $file !== '..') {
        $total += do_scan($dir . \DIRECTORY_SEPARATOR . $file, $dev);
      }
    }

    print "$total\t$dir\n";
  }

  return $total;
};

foreach (\array_slice($argv, 1) as $arg) {
  do_scan($arg, \lstat($arg)['dev']);
}

Put that in a file (say, "treesize"), chmod +x it and run it with ./treesize . | sort -rn | less.

Solution 2

I have found du --inodes useful, but I'm not sure which version of du it requires. On Ubuntu 17.10, the following works:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

Combine with | sort -nr to sort descending by number of containing inodes.

Solution 3

The easiest way seems to be find /path/to/search -ls | wc -l

Find is used to walk though all files and folders.
-ls to list (print) all the names. This is a default and if you leave it out it will still work the same almost all systems. (Almost, since some might have different defaults). It is a good habit to explicitly use this though.

If you just use the find /path/to/search -ls part it will print all the files and directories to your screen.


wc is word count. the -l option tells it to count the number of lines.

You can use it in several ways, e.g.

  • wc testfile
  • cat testfile | wc

The first option lets wc open a file and count the number of lines, words and chars in that file. The second option does the same but without filename it reads from stdin.


You can combime commands with a pipe |. Output from the first command will be piped to the input of the second command. Thus find /path/to/search -ls | wc -l uses find to list all files and directory and feeds the output to wc. Wc then counts the number of lines.

(An other alternative would have been `ls | wc', but find is much more flexible and a good tool to learn.)


[Edit after comment]

It might be useful to combine the find and the exec.

E.g. find / -type d ! \( -path proc -o -path dev -o -path .snap \) -maxdepth 1 -exec echo starting a find to count to files in in {} \; will list all directories in /, bar some which you do not want to search. We can trigger the previous command on each of them, yielding a sum of files per folder in /.

However:

  1. This uses the GNU specific extension -maxdepth.
    It will work on Linux, but not on just any unix-a-alike.
  2. I suspect you might actually want a number fo files for each and every subdir.

Solution 4

ncdu is great for this!

From the man page, you can show counts per directory and order by counts as well:

[...]
KEYS
       C   Order by number of items (press again for descending order)
[...]
       c   Toggle display of child item counts.

For example:

ncdu output

Solution 5

Here's a solution that uses bash, inspired by a post from Unix & Linux.

find . -type d | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

If there are some folders that you don't want to see the details of, like .git, you can exclude them from the list with grep.

find . -type d |grep -v "./.git/.*" | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Share:
708

Related videos on Youtube

coderone
Author by

coderone

Updated on September 18, 2022

Comments

  • coderone
    coderone over 1 year

    I'm trying to deploy my C# WPF Application with the Setup Wizard in Visual Studio 2019. When I install the application on my dev-computer, through the setup I made, it works fine and I can start the installed application and all things are working. When I install the application on another computer, it shows the SplashScreen and then nothing happened.

    I looked in the Event logs of windows and there are two errors for my application.

    1. Error (Log Name: Application, Source: .NET Runtime, Event ID: 1026, Level: Error)
    Application: VS_MVVM.exe
    Framework Version: v4.0.30319
    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.ComponentModel.Win32Exception
    
    Exception Info: System.Data.SqlClient.SqlException
       at System.Data.SqlClient.SqlInternalConnectionTds..ctor(System.Data.ProviderBase.DbConnectionPoolIdentity, System.Data.SqlClient.SqlConnectionString, System.Data.SqlClient.SqlCredential, System.Object, System.String, System.Security.SecureString, Boolean, System.Data.SqlClient.SqlConnectionString, System.Data.SqlClient.SessionData, System.Data.ProviderBase.DbConnectionPool, System.String, Boolean, System.Data.SqlClient.SqlAuthenticationProviderManager)
       at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(System.Data.Common.DbConnectionOptions, System.Data.Common.DbConnectionPoolKey, System.Object, System.Data.ProviderBase.DbConnectionPool, System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions)
       at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(System.Data.ProviderBase.DbConnectionPool, System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions, System.Data.Common.DbConnectionPoolKey, System.Data.Common.DbConnectionOptions)
       at System.Data.ProviderBase.DbConnectionPool.CreateObject(System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal)
       at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal)
       at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(System.Data.Common.DbConnection, UInt32, Boolean, Boolean, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal ByRef)
       at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(System.Data.Common.DbConnection, System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal ByRef)
       at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(System.Data.Common.DbConnection, System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal, System.Data.ProviderBase.DbConnectionInternal ByRef)
       at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory, System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions)
       at System.Data.SqlClient.SqlConnection.TryOpenInner(System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>)
       at System.Data.SqlClient.SqlConnection.TryOpen(System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>)
       at System.Data.SqlClient.SqlConnection.Open()
       at VS_MVVM.Model.LanguageCollection.GetSelectedLanguage()
       at VS_MVVM.ViewModel.MainViewModel.LoadLanguage()
       at VS_MVVM.ViewModel.MainViewModel..ctor()
    
    Exception Info: System.Windows.Markup.XamlParseException
       at System.Windows.Markup.XamlReader.RewrapException(System.Exception, System.Xaml.IXamlLineInfo, System.Uri)
       at System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader, System.Xaml.IXamlObjectWriterFactory, Boolean, System.Object, System.Xaml.XamlObjectWriterSettings, System.Uri)
       at System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader, Boolean, System.Object, System.Xaml.Permissions.XamlAccessLevel, System.Uri)
       at System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream, System.Windows.Markup.ParserContext, System.Object, Boolean)
       at System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream, System.Windows.Markup.ParserContext)
       at System.Windows.Application.DoStartup()
       at System.Windows.Application.<.ctor>b__1_0(System.Object)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
       at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
       at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
       at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
       at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
       at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
       at System.Windows.Application.RunDispatcher(System.Object)
       at System.Windows.Application.RunInternal(System.Windows.Window)
       at VS_MVVM.App.Main()
    
    1. Error (Log Name: Application, Source: Application Error, Event ID: 1000, Level: Error)
    Faulting application name: VS_MVVM.exe, version: 1.0.0.0, time stamp: 0xf0d82005
    Faulting module name: KERNELBASE.dll, version: 10.0.18362.356, time stamp: 0x7083db20
    Exception code: 0xe0434352
    Fault offset: 0x000000000003a839
    Faulting process id: 0x1d40
    Faulting application start time: 0x01d589b244b41838
    Faulting application path: C:\Program Files (x86)\Test\Test\VS_MVVM.exe
    Faulting module path: C:\Windows\System32\KERNELBASE.dll
    Report Id: cd987b9b-2182-4587-8b2f-25389663ea9a
    Faulting package full name: 
    Faulting package-relative application ID: 
    

    I've tried to reinstall SQL Server or the .NET Framework and nothing helped.

    I don't know where the problem is and I didn't found an answer on the internet.

    • James
      James about 11 years
      Think you might be looking for something like a slightly modified version of the answers here superuser.com/questions/198817/…
    • Nawed Nabi Zada
      Nawed Nabi Zada over 4 years
      Make sure all dependencies are copied with your installation. Check your Solution.Project.References is there any DLL, project reference which does not exist on target computer ?
    • coderone
      coderone over 4 years
      They were all copied except the references of the .NET Framework
    • SledgeHammer
      SledgeHammer over 4 years
      It tells you the problem in the call stack. The VS_MVVM.Model.LanguageCollection.GetSelectedLanguage() method failed on the SQL connection. Maybe your connection string is bad? Firewall, etc?
    • coderone
      coderone over 4 years
      The connectionString is correct. The database file is a local file and is placed in the AppData folder in users folder. So there should be no permission issue.
  • Ярослав Рахматуллин
    Ярослав Рахматуллин about 11 years
    Why do I have .fluxbox in / ? :D
  • Jesse
    Jesse about 11 years
    Sorry, not just one level deep though, but for all levels (that's what I meant by "recursively" in my edit).
  • ganesh
    ganesh about 11 years
    Instead of the exec echo you trigger a find | wc for each dir. I know it is possible, but I can't seem to discover how today. I guess I keep making the same mistake somehow. * Goes to brew coffee * .
  • user1810087
    user1810087 almost 6 years
    Why is this the accepted answer?! You are assuming php is on the machine, which is not always the case. The script is not documented and to specific. While it is ok to answer your own question on SE, this answer does not even provide an Answer to your own question; or you did not asked the question you had in mind when the problem occured... Unfortunately I cannot downvote it, I have to few point... still, bad answer!
  • Jesse
    Jesse almost 6 years
    I can't write the script in any language without assuming an interpreter for that language is installed. The script prints the total number of files and directories beneath each directory recursively. So a du that simply counts instead of summing size, which is exactly what the original question asked.
  • Sridhar Sarnobat
    Sridhar Sarnobat about 5 years
    This looks a lot more like what I want than the accepted answer.
  • Steven the Easily Amused
    Steven the Easily Amused over 3 years
    find /path/to/search -ls | wc -l is a lot more "expensive" than find /path/to/search | wc -l (which does a print by default, but can be done like this find /path/to/search -print | wc -l Why? because -ls has to stat the file to print the long form that ls -l would print... but after all that you're just counting Newlines (wc -l). In fact this trick is the fastest I've found to count all files and directories: find . -printf 'x' | wc -c It turns each directory or file into a single "x" then wc counts the total characters.
  • KarolDepka
    KarolDepka over 2 years
    Hi. On macOS, You can use gdu --inodes instead of du: gdu --inodes | sort -n - seems to work usefully and REALLY FAST. Requires brew install coreutils IIRC.