Directories with two or more files

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
11
down vote

favorite
1












I want to find a subdirectory of the current directory, which (that is the subdirectory) contains 2 or more regular files.



I am not interested in directories containing less than 2 files, neither in directories which contain only subdirectories.










share|improve this question



























    up vote
    11
    down vote

    favorite
    1












    I want to find a subdirectory of the current directory, which (that is the subdirectory) contains 2 or more regular files.



    I am not interested in directories containing less than 2 files, neither in directories which contain only subdirectories.










    share|improve this question

























      up vote
      11
      down vote

      favorite
      1









      up vote
      11
      down vote

      favorite
      1






      1





      I want to find a subdirectory of the current directory, which (that is the subdirectory) contains 2 or more regular files.



      I am not interested in directories containing less than 2 files, neither in directories which contain only subdirectories.










      share|improve this question















      I want to find a subdirectory of the current directory, which (that is the subdirectory) contains 2 or more regular files.



      I am not interested in directories containing less than 2 files, neither in directories which contain only subdirectories.







      files find






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 8 '17 at 14:43









      αғsнιη

      15.6k92563




      15.6k92563










      asked Oct 8 '17 at 13:09









      porton

      9781020




      9781020




















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          11
          down vote



          accepted










          Here is a completely different approach based on GNU find and uniq. This is much faster and much CPU-friendly than answers based on executing a shell command that counts files for each directory found.



          find . -type f -printf '%hn' | sort | uniq -d


          The find command prints the directory of all files in the hierarchy and uniq only displays the directories that appear at least twice.






          share|improve this answer
















          • 2




            You shouldn't parse the output of find. In this case, because GNU find will mangle the names of directories that have characters that are not printable in the current locale (like "ä" in the C locale). See also unix.stackexchange.com/questions/321697/…
            – Kusalananda
            Oct 9 '17 at 5:33






          • 4




            @Kusalananda, not when the output doesn't go to a tty. Here, the only problem is with the newline characters, which you can fix by using -printf '%h' | sort -z | uniq -zd | xargs -r0 ...
            – Stéphane Chazelas
            Oct 9 '17 at 16:11


















          up vote
          6
          down vote













          find . -type d 
          -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';'
          -print


          This will find all names in or under the current directory and then filter out all names that are not names of directories.



          The remaining directory names will be given to this short script:



          c=0
          for n in "$1"/*; do
          [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
          done

          [ "$c" -ge 2 ]


          This script will count the number of regular files (skipping symbolic links) in the directory given as the first command line argument (from find). The last command in the script is a test to see if the count was 2 or greater. The result of this test is the return value (exit status) of the script.



          If the test succeeded, -print will cause find to print out the path to the directory.



          To also consider hidden files (files whose names begins with a dot), change the sh -c script from saying



          for n in "$1"/*; do


          to



          for n in "$1"/* "$1"/.*; do



          Testing:



          $ tree
          .
          `-- test
          |-- a
          |-- dir1
          | |-- a
          | |-- b
          | `-- c
          `-- dir2
          |-- dira
          |-- dirb
          | |-- file-1
          | `-- file-2
          `-- dirc

          6 directories, 6 files

          $ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';' -print
          ./test/dir1
          ./test/dir2/dirb





          share|improve this answer






















          • Your solution doesn't count files with a name starting with a dot. You should also initialize c=0 in order to avoid error messages with directories that do not contain any file.
            – xhienne
            Oct 8 '17 at 14:20











          • @xhienne I considered hidden files and will add a note about it. There is no error if there are no regular files in a directory since [ "" -ge 2 ] is a valid test.
            – Kusalananda
            Oct 8 '17 at 14:25










          • Not sure how you define "valid". POSIX requires arg1 to be an integer value. dash, bash --posix and test all display an error message and exit with 2 (i.e. "An error occurred")
            – xhienne
            Oct 8 '17 at 14:36










          • @xhienne Ah, I was testing on a system that mas ksh running as sh. Will amend immediately. Thanks for poking at me! :-)
            – Kusalananda
            Oct 8 '17 at 15:00











          • Also, [ -f ... ] dereferences symbolic links. You should add a test to eliminate them since the question specifies that only regular files should be counted.
            – xhienne
            Oct 8 '17 at 15:49

















          up vote
          6
          down vote













          With the help of Gilles's answer on SU and its reverse and some modification, here what you need.



          find . -type d -exec sh -c 'set -- "$1"/*;X=0; 
          for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ ; -print


          Directory tree.



          .
          ├── test
          │   ├── dir1
          │   │   ├── a
          │   │   ├── b
          │   │   └── c
          │   ├── dir2
          │   │   ├── dira
          │   │   │   └── a file12with12multiple12line
          │   │   ├── dirb
          │   │   │   ├── file-1
          │   │   │   └── file-2
          │   │   └── dirc
          │   ├── diraa
          │   ├── dirbb
          │   ├── dircc
          │   └── x
          │   └── x1
          │   └── x2
          └── test2
          ├── dir3
          └── dir4


          Result:



          ./test
          ./test/dir1
          ./test/dir2/dirb





          share|improve this answer






















          • I had this at first too, but you will have problem with directories containing multiple subdirectories and files. It also does not weed out directories only containing subdirectories.
            – Kusalananda
            Oct 8 '17 at 13:36











          • It doesn't really solve it. It finds both the test and the dir2 directories in my test setup (see my answer).
            – Kusalananda
            Oct 8 '17 at 13:40











          • Works for your example, but add test/x1 and test/x2 as files as well... $1 and $2 will be directories for test, and the directory will be missed.
            – Kusalananda
            Oct 8 '17 at 14:47










          • @Kusalananda No way I found except what you answered, I tried to change some part of my command to don't be exact duplicate of yours (I didn't exclude hidden files as you did), my apologize.
            – Î±Ò“sнιη
            Oct 8 '17 at 16:04







          • 1




            No worries whatsoever :-)
            – Kusalananda
            Oct 8 '17 at 16:10

















          up vote
          3
          down vote













          Another find + wc approach:



          find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" 
          -exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ ; -print



          • path/currdir - path to your current directory


          • -maxdepth 1 - consider only direct child subfolders


          • ! -empty - ignore empty subfolders


          • ! -path "path/currdir" - ignore the current directory path


          • count=$(find "$1" -maxdepth 1 -type f | wc -l) - count is assigned with the number of files for each found subfolder


          • [ $count -ge 2 ] ... -print - print subfolder name/path containing 2 or more regular files






          share|improve this answer






















            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',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f396826%2fdirectories-with-two-or-more-files%23new-answer', 'question_page');

            );

            Post as a guest






























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            11
            down vote



            accepted










            Here is a completely different approach based on GNU find and uniq. This is much faster and much CPU-friendly than answers based on executing a shell command that counts files for each directory found.



            find . -type f -printf '%hn' | sort | uniq -d


            The find command prints the directory of all files in the hierarchy and uniq only displays the directories that appear at least twice.






            share|improve this answer
















            • 2




              You shouldn't parse the output of find. In this case, because GNU find will mangle the names of directories that have characters that are not printable in the current locale (like "ä" in the C locale). See also unix.stackexchange.com/questions/321697/…
              – Kusalananda
              Oct 9 '17 at 5:33






            • 4




              @Kusalananda, not when the output doesn't go to a tty. Here, the only problem is with the newline characters, which you can fix by using -printf '%h' | sort -z | uniq -zd | xargs -r0 ...
              – Stéphane Chazelas
              Oct 9 '17 at 16:11















            up vote
            11
            down vote



            accepted










            Here is a completely different approach based on GNU find and uniq. This is much faster and much CPU-friendly than answers based on executing a shell command that counts files for each directory found.



            find . -type f -printf '%hn' | sort | uniq -d


            The find command prints the directory of all files in the hierarchy and uniq only displays the directories that appear at least twice.






            share|improve this answer
















            • 2




              You shouldn't parse the output of find. In this case, because GNU find will mangle the names of directories that have characters that are not printable in the current locale (like "ä" in the C locale). See also unix.stackexchange.com/questions/321697/…
              – Kusalananda
              Oct 9 '17 at 5:33






            • 4




              @Kusalananda, not when the output doesn't go to a tty. Here, the only problem is with the newline characters, which you can fix by using -printf '%h' | sort -z | uniq -zd | xargs -r0 ...
              – Stéphane Chazelas
              Oct 9 '17 at 16:11













            up vote
            11
            down vote



            accepted







            up vote
            11
            down vote



            accepted






            Here is a completely different approach based on GNU find and uniq. This is much faster and much CPU-friendly than answers based on executing a shell command that counts files for each directory found.



            find . -type f -printf '%hn' | sort | uniq -d


            The find command prints the directory of all files in the hierarchy and uniq only displays the directories that appear at least twice.






            share|improve this answer












            Here is a completely different approach based on GNU find and uniq. This is much faster and much CPU-friendly than answers based on executing a shell command that counts files for each directory found.



            find . -type f -printf '%hn' | sort | uniq -d


            The find command prints the directory of all files in the hierarchy and uniq only displays the directories that appear at least twice.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 8 '17 at 15:45









            xhienne

            11.7k2553




            11.7k2553







            • 2




              You shouldn't parse the output of find. In this case, because GNU find will mangle the names of directories that have characters that are not printable in the current locale (like "ä" in the C locale). See also unix.stackexchange.com/questions/321697/…
              – Kusalananda
              Oct 9 '17 at 5:33






            • 4




              @Kusalananda, not when the output doesn't go to a tty. Here, the only problem is with the newline characters, which you can fix by using -printf '%h' | sort -z | uniq -zd | xargs -r0 ...
              – Stéphane Chazelas
              Oct 9 '17 at 16:11













            • 2




              You shouldn't parse the output of find. In this case, because GNU find will mangle the names of directories that have characters that are not printable in the current locale (like "ä" in the C locale). See also unix.stackexchange.com/questions/321697/…
              – Kusalananda
              Oct 9 '17 at 5:33






            • 4




              @Kusalananda, not when the output doesn't go to a tty. Here, the only problem is with the newline characters, which you can fix by using -printf '%h' | sort -z | uniq -zd | xargs -r0 ...
              – Stéphane Chazelas
              Oct 9 '17 at 16:11








            2




            2




            You shouldn't parse the output of find. In this case, because GNU find will mangle the names of directories that have characters that are not printable in the current locale (like "ä" in the C locale). See also unix.stackexchange.com/questions/321697/…
            – Kusalananda
            Oct 9 '17 at 5:33




            You shouldn't parse the output of find. In this case, because GNU find will mangle the names of directories that have characters that are not printable in the current locale (like "ä" in the C locale). See also unix.stackexchange.com/questions/321697/…
            – Kusalananda
            Oct 9 '17 at 5:33




            4




            4




            @Kusalananda, not when the output doesn't go to a tty. Here, the only problem is with the newline characters, which you can fix by using -printf '%h' | sort -z | uniq -zd | xargs -r0 ...
            – Stéphane Chazelas
            Oct 9 '17 at 16:11





            @Kusalananda, not when the output doesn't go to a tty. Here, the only problem is with the newline characters, which you can fix by using -printf '%h' | sort -z | uniq -zd | xargs -r0 ...
            – Stéphane Chazelas
            Oct 9 '17 at 16:11













            up vote
            6
            down vote













            find . -type d 
            -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';'
            -print


            This will find all names in or under the current directory and then filter out all names that are not names of directories.



            The remaining directory names will be given to this short script:



            c=0
            for n in "$1"/*; do
            [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
            done

            [ "$c" -ge 2 ]


            This script will count the number of regular files (skipping symbolic links) in the directory given as the first command line argument (from find). The last command in the script is a test to see if the count was 2 or greater. The result of this test is the return value (exit status) of the script.



            If the test succeeded, -print will cause find to print out the path to the directory.



            To also consider hidden files (files whose names begins with a dot), change the sh -c script from saying



            for n in "$1"/*; do


            to



            for n in "$1"/* "$1"/.*; do



            Testing:



            $ tree
            .
            `-- test
            |-- a
            |-- dir1
            | |-- a
            | |-- b
            | `-- c
            `-- dir2
            |-- dira
            |-- dirb
            | |-- file-1
            | `-- file-2
            `-- dirc

            6 directories, 6 files

            $ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';' -print
            ./test/dir1
            ./test/dir2/dirb





            share|improve this answer






















            • Your solution doesn't count files with a name starting with a dot. You should also initialize c=0 in order to avoid error messages with directories that do not contain any file.
              – xhienne
              Oct 8 '17 at 14:20











            • @xhienne I considered hidden files and will add a note about it. There is no error if there are no regular files in a directory since [ "" -ge 2 ] is a valid test.
              – Kusalananda
              Oct 8 '17 at 14:25










            • Not sure how you define "valid". POSIX requires arg1 to be an integer value. dash, bash --posix and test all display an error message and exit with 2 (i.e. "An error occurred")
              – xhienne
              Oct 8 '17 at 14:36










            • @xhienne Ah, I was testing on a system that mas ksh running as sh. Will amend immediately. Thanks for poking at me! :-)
              – Kusalananda
              Oct 8 '17 at 15:00











            • Also, [ -f ... ] dereferences symbolic links. You should add a test to eliminate them since the question specifies that only regular files should be counted.
              – xhienne
              Oct 8 '17 at 15:49














            up vote
            6
            down vote













            find . -type d 
            -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';'
            -print


            This will find all names in or under the current directory and then filter out all names that are not names of directories.



            The remaining directory names will be given to this short script:



            c=0
            for n in "$1"/*; do
            [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
            done

            [ "$c" -ge 2 ]


            This script will count the number of regular files (skipping symbolic links) in the directory given as the first command line argument (from find). The last command in the script is a test to see if the count was 2 or greater. The result of this test is the return value (exit status) of the script.



            If the test succeeded, -print will cause find to print out the path to the directory.



            To also consider hidden files (files whose names begins with a dot), change the sh -c script from saying



            for n in "$1"/*; do


            to



            for n in "$1"/* "$1"/.*; do



            Testing:



            $ tree
            .
            `-- test
            |-- a
            |-- dir1
            | |-- a
            | |-- b
            | `-- c
            `-- dir2
            |-- dira
            |-- dirb
            | |-- file-1
            | `-- file-2
            `-- dirc

            6 directories, 6 files

            $ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';' -print
            ./test/dir1
            ./test/dir2/dirb





            share|improve this answer






















            • Your solution doesn't count files with a name starting with a dot. You should also initialize c=0 in order to avoid error messages with directories that do not contain any file.
              – xhienne
              Oct 8 '17 at 14:20











            • @xhienne I considered hidden files and will add a note about it. There is no error if there are no regular files in a directory since [ "" -ge 2 ] is a valid test.
              – Kusalananda
              Oct 8 '17 at 14:25










            • Not sure how you define "valid". POSIX requires arg1 to be an integer value. dash, bash --posix and test all display an error message and exit with 2 (i.e. "An error occurred")
              – xhienne
              Oct 8 '17 at 14:36










            • @xhienne Ah, I was testing on a system that mas ksh running as sh. Will amend immediately. Thanks for poking at me! :-)
              – Kusalananda
              Oct 8 '17 at 15:00











            • Also, [ -f ... ] dereferences symbolic links. You should add a test to eliminate them since the question specifies that only regular files should be counted.
              – xhienne
              Oct 8 '17 at 15:49












            up vote
            6
            down vote










            up vote
            6
            down vote









            find . -type d 
            -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';'
            -print


            This will find all names in or under the current directory and then filter out all names that are not names of directories.



            The remaining directory names will be given to this short script:



            c=0
            for n in "$1"/*; do
            [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
            done

            [ "$c" -ge 2 ]


            This script will count the number of regular files (skipping symbolic links) in the directory given as the first command line argument (from find). The last command in the script is a test to see if the count was 2 or greater. The result of this test is the return value (exit status) of the script.



            If the test succeeded, -print will cause find to print out the path to the directory.



            To also consider hidden files (files whose names begins with a dot), change the sh -c script from saying



            for n in "$1"/*; do


            to



            for n in "$1"/* "$1"/.*; do



            Testing:



            $ tree
            .
            `-- test
            |-- a
            |-- dir1
            | |-- a
            | |-- b
            | `-- c
            `-- dir2
            |-- dira
            |-- dirb
            | |-- file-1
            | `-- file-2
            `-- dirc

            6 directories, 6 files

            $ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';' -print
            ./test/dir1
            ./test/dir2/dirb





            share|improve this answer














            find . -type d 
            -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';'
            -print


            This will find all names in or under the current directory and then filter out all names that are not names of directories.



            The remaining directory names will be given to this short script:



            c=0
            for n in "$1"/*; do
            [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
            done

            [ "$c" -ge 2 ]


            This script will count the number of regular files (skipping symbolic links) in the directory given as the first command line argument (from find). The last command in the script is a test to see if the count was 2 or greater. The result of this test is the return value (exit status) of the script.



            If the test succeeded, -print will cause find to print out the path to the directory.



            To also consider hidden files (files whose names begins with a dot), change the sh -c script from saying



            for n in "$1"/*; do


            to



            for n in "$1"/* "$1"/.*; do



            Testing:



            $ tree
            .
            `-- test
            |-- a
            |-- dir1
            | |-- a
            | |-- b
            | `-- c
            `-- dir2
            |-- dira
            |-- dirb
            | |-- file-1
            | `-- file-2
            `-- dirc

            6 directories, 6 files

            $ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh ';' -print
            ./test/dir1
            ./test/dir2/dirb






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Oct 8 '17 at 15:52

























            answered Oct 8 '17 at 13:19









            Kusalananda

            105k14209326




            105k14209326











            • Your solution doesn't count files with a name starting with a dot. You should also initialize c=0 in order to avoid error messages with directories that do not contain any file.
              – xhienne
              Oct 8 '17 at 14:20











            • @xhienne I considered hidden files and will add a note about it. There is no error if there are no regular files in a directory since [ "" -ge 2 ] is a valid test.
              – Kusalananda
              Oct 8 '17 at 14:25










            • Not sure how you define "valid". POSIX requires arg1 to be an integer value. dash, bash --posix and test all display an error message and exit with 2 (i.e. "An error occurred")
              – xhienne
              Oct 8 '17 at 14:36










            • @xhienne Ah, I was testing on a system that mas ksh running as sh. Will amend immediately. Thanks for poking at me! :-)
              – Kusalananda
              Oct 8 '17 at 15:00











            • Also, [ -f ... ] dereferences symbolic links. You should add a test to eliminate them since the question specifies that only regular files should be counted.
              – xhienne
              Oct 8 '17 at 15:49
















            • Your solution doesn't count files with a name starting with a dot. You should also initialize c=0 in order to avoid error messages with directories that do not contain any file.
              – xhienne
              Oct 8 '17 at 14:20











            • @xhienne I considered hidden files and will add a note about it. There is no error if there are no regular files in a directory since [ "" -ge 2 ] is a valid test.
              – Kusalananda
              Oct 8 '17 at 14:25










            • Not sure how you define "valid". POSIX requires arg1 to be an integer value. dash, bash --posix and test all display an error message and exit with 2 (i.e. "An error occurred")
              – xhienne
              Oct 8 '17 at 14:36










            • @xhienne Ah, I was testing on a system that mas ksh running as sh. Will amend immediately. Thanks for poking at me! :-)
              – Kusalananda
              Oct 8 '17 at 15:00











            • Also, [ -f ... ] dereferences symbolic links. You should add a test to eliminate them since the question specifies that only regular files should be counted.
              – xhienne
              Oct 8 '17 at 15:49















            Your solution doesn't count files with a name starting with a dot. You should also initialize c=0 in order to avoid error messages with directories that do not contain any file.
            – xhienne
            Oct 8 '17 at 14:20





            Your solution doesn't count files with a name starting with a dot. You should also initialize c=0 in order to avoid error messages with directories that do not contain any file.
            – xhienne
            Oct 8 '17 at 14:20













            @xhienne I considered hidden files and will add a note about it. There is no error if there are no regular files in a directory since [ "" -ge 2 ] is a valid test.
            – Kusalananda
            Oct 8 '17 at 14:25




            @xhienne I considered hidden files and will add a note about it. There is no error if there are no regular files in a directory since [ "" -ge 2 ] is a valid test.
            – Kusalananda
            Oct 8 '17 at 14:25












            Not sure how you define "valid". POSIX requires arg1 to be an integer value. dash, bash --posix and test all display an error message and exit with 2 (i.e. "An error occurred")
            – xhienne
            Oct 8 '17 at 14:36




            Not sure how you define "valid". POSIX requires arg1 to be an integer value. dash, bash --posix and test all display an error message and exit with 2 (i.e. "An error occurred")
            – xhienne
            Oct 8 '17 at 14:36












            @xhienne Ah, I was testing on a system that mas ksh running as sh. Will amend immediately. Thanks for poking at me! :-)
            – Kusalananda
            Oct 8 '17 at 15:00





            @xhienne Ah, I was testing on a system that mas ksh running as sh. Will amend immediately. Thanks for poking at me! :-)
            – Kusalananda
            Oct 8 '17 at 15:00













            Also, [ -f ... ] dereferences symbolic links. You should add a test to eliminate them since the question specifies that only regular files should be counted.
            – xhienne
            Oct 8 '17 at 15:49




            Also, [ -f ... ] dereferences symbolic links. You should add a test to eliminate them since the question specifies that only regular files should be counted.
            – xhienne
            Oct 8 '17 at 15:49










            up vote
            6
            down vote













            With the help of Gilles's answer on SU and its reverse and some modification, here what you need.



            find . -type d -exec sh -c 'set -- "$1"/*;X=0; 
            for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ ; -print


            Directory tree.



            .
            ├── test
            │   ├── dir1
            │   │   ├── a
            │   │   ├── b
            │   │   └── c
            │   ├── dir2
            │   │   ├── dira
            │   │   │   └── a file12with12multiple12line
            │   │   ├── dirb
            │   │   │   ├── file-1
            │   │   │   └── file-2
            │   │   └── dirc
            │   ├── diraa
            │   ├── dirbb
            │   ├── dircc
            │   └── x
            │   └── x1
            │   └── x2
            └── test2
            ├── dir3
            └── dir4


            Result:



            ./test
            ./test/dir1
            ./test/dir2/dirb





            share|improve this answer






















            • I had this at first too, but you will have problem with directories containing multiple subdirectories and files. It also does not weed out directories only containing subdirectories.
              – Kusalananda
              Oct 8 '17 at 13:36











            • It doesn't really solve it. It finds both the test and the dir2 directories in my test setup (see my answer).
              – Kusalananda
              Oct 8 '17 at 13:40











            • Works for your example, but add test/x1 and test/x2 as files as well... $1 and $2 will be directories for test, and the directory will be missed.
              – Kusalananda
              Oct 8 '17 at 14:47










            • @Kusalananda No way I found except what you answered, I tried to change some part of my command to don't be exact duplicate of yours (I didn't exclude hidden files as you did), my apologize.
              – Î±Ò“sнιη
              Oct 8 '17 at 16:04







            • 1




              No worries whatsoever :-)
              – Kusalananda
              Oct 8 '17 at 16:10














            up vote
            6
            down vote













            With the help of Gilles's answer on SU and its reverse and some modification, here what you need.



            find . -type d -exec sh -c 'set -- "$1"/*;X=0; 
            for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ ; -print


            Directory tree.



            .
            ├── test
            │   ├── dir1
            │   │   ├── a
            │   │   ├── b
            │   │   └── c
            │   ├── dir2
            │   │   ├── dira
            │   │   │   └── a file12with12multiple12line
            │   │   ├── dirb
            │   │   │   ├── file-1
            │   │   │   └── file-2
            │   │   └── dirc
            │   ├── diraa
            │   ├── dirbb
            │   ├── dircc
            │   └── x
            │   └── x1
            │   └── x2
            └── test2
            ├── dir3
            └── dir4


            Result:



            ./test
            ./test/dir1
            ./test/dir2/dirb





            share|improve this answer






















            • I had this at first too, but you will have problem with directories containing multiple subdirectories and files. It also does not weed out directories only containing subdirectories.
              – Kusalananda
              Oct 8 '17 at 13:36











            • It doesn't really solve it. It finds both the test and the dir2 directories in my test setup (see my answer).
              – Kusalananda
              Oct 8 '17 at 13:40











            • Works for your example, but add test/x1 and test/x2 as files as well... $1 and $2 will be directories for test, and the directory will be missed.
              – Kusalananda
              Oct 8 '17 at 14:47










            • @Kusalananda No way I found except what you answered, I tried to change some part of my command to don't be exact duplicate of yours (I didn't exclude hidden files as you did), my apologize.
              – Î±Ò“sнιη
              Oct 8 '17 at 16:04







            • 1




              No worries whatsoever :-)
              – Kusalananda
              Oct 8 '17 at 16:10












            up vote
            6
            down vote










            up vote
            6
            down vote









            With the help of Gilles's answer on SU and its reverse and some modification, here what you need.



            find . -type d -exec sh -c 'set -- "$1"/*;X=0; 
            for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ ; -print


            Directory tree.



            .
            ├── test
            │   ├── dir1
            │   │   ├── a
            │   │   ├── b
            │   │   └── c
            │   ├── dir2
            │   │   ├── dira
            │   │   │   └── a file12with12multiple12line
            │   │   ├── dirb
            │   │   │   ├── file-1
            │   │   │   └── file-2
            │   │   └── dirc
            │   ├── diraa
            │   ├── dirbb
            │   ├── dircc
            │   └── x
            │   └── x1
            │   └── x2
            └── test2
            ├── dir3
            └── dir4


            Result:



            ./test
            ./test/dir1
            ./test/dir2/dirb





            share|improve this answer














            With the help of Gilles's answer on SU and its reverse and some modification, here what you need.



            find . -type d -exec sh -c 'set -- "$1"/*;X=0; 
            for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ ; -print


            Directory tree.



            .
            ├── test
            │   ├── dir1
            │   │   ├── a
            │   │   ├── b
            │   │   └── c
            │   ├── dir2
            │   │   ├── dira
            │   │   │   └── a file12with12multiple12line
            │   │   ├── dirb
            │   │   │   ├── file-1
            │   │   │   └── file-2
            │   │   └── dirc
            │   ├── diraa
            │   ├── dirbb
            │   ├── dircc
            │   └── x
            │   └── x1
            │   └── x2
            └── test2
            ├── dir3
            └── dir4


            Result:



            ./test
            ./test/dir1
            ./test/dir2/dirb






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Oct 8 '17 at 16:02

























            answered Oct 8 '17 at 13:35









            αғsнιη

            15.6k92563




            15.6k92563











            • I had this at first too, but you will have problem with directories containing multiple subdirectories and files. It also does not weed out directories only containing subdirectories.
              – Kusalananda
              Oct 8 '17 at 13:36











            • It doesn't really solve it. It finds both the test and the dir2 directories in my test setup (see my answer).
              – Kusalananda
              Oct 8 '17 at 13:40











            • Works for your example, but add test/x1 and test/x2 as files as well... $1 and $2 will be directories for test, and the directory will be missed.
              – Kusalananda
              Oct 8 '17 at 14:47










            • @Kusalananda No way I found except what you answered, I tried to change some part of my command to don't be exact duplicate of yours (I didn't exclude hidden files as you did), my apologize.
              – Î±Ò“sнιη
              Oct 8 '17 at 16:04







            • 1




              No worries whatsoever :-)
              – Kusalananda
              Oct 8 '17 at 16:10
















            • I had this at first too, but you will have problem with directories containing multiple subdirectories and files. It also does not weed out directories only containing subdirectories.
              – Kusalananda
              Oct 8 '17 at 13:36











            • It doesn't really solve it. It finds both the test and the dir2 directories in my test setup (see my answer).
              – Kusalananda
              Oct 8 '17 at 13:40











            • Works for your example, but add test/x1 and test/x2 as files as well... $1 and $2 will be directories for test, and the directory will be missed.
              – Kusalananda
              Oct 8 '17 at 14:47










            • @Kusalananda No way I found except what you answered, I tried to change some part of my command to don't be exact duplicate of yours (I didn't exclude hidden files as you did), my apologize.
              – Î±Ò“sнιη
              Oct 8 '17 at 16:04







            • 1




              No worries whatsoever :-)
              – Kusalananda
              Oct 8 '17 at 16:10















            I had this at first too, but you will have problem with directories containing multiple subdirectories and files. It also does not weed out directories only containing subdirectories.
            – Kusalananda
            Oct 8 '17 at 13:36





            I had this at first too, but you will have problem with directories containing multiple subdirectories and files. It also does not weed out directories only containing subdirectories.
            – Kusalananda
            Oct 8 '17 at 13:36













            It doesn't really solve it. It finds both the test and the dir2 directories in my test setup (see my answer).
            – Kusalananda
            Oct 8 '17 at 13:40





            It doesn't really solve it. It finds both the test and the dir2 directories in my test setup (see my answer).
            – Kusalananda
            Oct 8 '17 at 13:40













            Works for your example, but add test/x1 and test/x2 as files as well... $1 and $2 will be directories for test, and the directory will be missed.
            – Kusalananda
            Oct 8 '17 at 14:47




            Works for your example, but add test/x1 and test/x2 as files as well... $1 and $2 will be directories for test, and the directory will be missed.
            – Kusalananda
            Oct 8 '17 at 14:47












            @Kusalananda No way I found except what you answered, I tried to change some part of my command to don't be exact duplicate of yours (I didn't exclude hidden files as you did), my apologize.
            – Î±Ò“sнιη
            Oct 8 '17 at 16:04





            @Kusalananda No way I found except what you answered, I tried to change some part of my command to don't be exact duplicate of yours (I didn't exclude hidden files as you did), my apologize.
            – Î±Ò“sнιη
            Oct 8 '17 at 16:04





            1




            1




            No worries whatsoever :-)
            – Kusalananda
            Oct 8 '17 at 16:10




            No worries whatsoever :-)
            – Kusalananda
            Oct 8 '17 at 16:10










            up vote
            3
            down vote













            Another find + wc approach:



            find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" 
            -exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ ; -print



            • path/currdir - path to your current directory


            • -maxdepth 1 - consider only direct child subfolders


            • ! -empty - ignore empty subfolders


            • ! -path "path/currdir" - ignore the current directory path


            • count=$(find "$1" -maxdepth 1 -type f | wc -l) - count is assigned with the number of files for each found subfolder


            • [ $count -ge 2 ] ... -print - print subfolder name/path containing 2 or more regular files






            share|improve this answer


























              up vote
              3
              down vote













              Another find + wc approach:



              find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" 
              -exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ ; -print



              • path/currdir - path to your current directory


              • -maxdepth 1 - consider only direct child subfolders


              • ! -empty - ignore empty subfolders


              • ! -path "path/currdir" - ignore the current directory path


              • count=$(find "$1" -maxdepth 1 -type f | wc -l) - count is assigned with the number of files for each found subfolder


              • [ $count -ge 2 ] ... -print - print subfolder name/path containing 2 or more regular files






              share|improve this answer
























                up vote
                3
                down vote










                up vote
                3
                down vote









                Another find + wc approach:



                find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" 
                -exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ ; -print



                • path/currdir - path to your current directory


                • -maxdepth 1 - consider only direct child subfolders


                • ! -empty - ignore empty subfolders


                • ! -path "path/currdir" - ignore the current directory path


                • count=$(find "$1" -maxdepth 1 -type f | wc -l) - count is assigned with the number of files for each found subfolder


                • [ $count -ge 2 ] ... -print - print subfolder name/path containing 2 or more regular files






                share|improve this answer














                Another find + wc approach:



                find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" 
                -exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ ; -print



                • path/currdir - path to your current directory


                • -maxdepth 1 - consider only direct child subfolders


                • ! -empty - ignore empty subfolders


                • ! -path "path/currdir" - ignore the current directory path


                • count=$(find "$1" -maxdepth 1 -type f | wc -l) - count is assigned with the number of files for each found subfolder


                • [ $count -ge 2 ] ... -print - print subfolder name/path containing 2 or more regular files







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Oct 8 '17 at 13:50

























                answered Oct 8 '17 at 13:38









                RomanPerekhrest

                22.5k12145




                22.5k12145



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f396826%2fdirectories-with-two-or-more-files%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Bahrain

                    Postfix configuration issue with fips on centos 7; mailgun relay