How to find directories containing only specific filesuse 'find' to search for directories !containing certain filetype fooFind directories without music filesHow to show distinct directories on find?Copying Only Directories With FilesFind all .php files inside directories with writable permissionslist all directories containing *.html files and also list the files in the directoriesFind files in globbed directories excluding some subpaths

Telephone number in spoken words

Regex crossword (sudoku?)

(A room / an office) where an artist works

Is there any way to stop a user from creating executables and running them?

How do some PhD students get 10+ papers? Is that what I need for landing good faculty position?

80's/90's superhero cartoon with a man on fire and a man who made ice runways like Frozone

What's this phrase on the wall of a toilet of a French château ?

crippling fear of hellfire &, damnation, please help?

Are there any other rule mechanics that could grant Thieves' Cant?

Why is the result of ('b'+'a'+ + 'a' + 'a').toLowerCase() 'banana'?

Do I have to cite common CS algorithms?

How is являться different from есть and быть

Case Condition for two lines

Can I enter the USA with an E-2 visa and a one way flight ticket?

Corroded Metal vs Magical Armor, should it melt it?

Are employers legally allowed to pay employees in goods and services equal to or greater than the minimum wage?

Markov-chain sentence generator in Python

Why command hierarchy, if the chain of command is standing next to each other?

Does Nightpack Ambusher's second ability trigger if I cast spells during the end step?

Why is statically linking glibc discouraged?

Are 变 and 変 the same?

Split phone numbers into groups based on first digit

What is a good class if we remove subclasses?

How can God warn people of the upcoming rapture without disrupting society?



How to find directories containing only specific files


use 'find' to search for directories !containing certain filetype fooFind directories without music filesHow to show distinct directories on find?Copying Only Directories With FilesFind all .php files inside directories with writable permissionslist all directories containing *.html files and also list the files in the directoriesFind files in globbed directories excluding some subpaths






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3















I have several directories with useless files (like *.tmp, desktop.ini, Thumbs.db, .picasa.ini).



How to scan all drives to find directories which contain nothing but some of those files?










share|improve this question









New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Do you actually need to find the directories, or are you just going to delete those useless files and the directories? In the second case, you could just first delete the useless files, and then delete all now-empty directories. (Which would of course also remove any directories that were empty to begin with.)

    – ilkkachu
    7 hours ago


















3















I have several directories with useless files (like *.tmp, desktop.ini, Thumbs.db, .picasa.ini).



How to scan all drives to find directories which contain nothing but some of those files?










share|improve this question









New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Do you actually need to find the directories, or are you just going to delete those useless files and the directories? In the second case, you could just first delete the useless files, and then delete all now-empty directories. (Which would of course also remove any directories that were empty to begin with.)

    – ilkkachu
    7 hours ago














3












3








3


1






I have several directories with useless files (like *.tmp, desktop.ini, Thumbs.db, .picasa.ini).



How to scan all drives to find directories which contain nothing but some of those files?










share|improve this question









New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I have several directories with useless files (like *.tmp, desktop.ini, Thumbs.db, .picasa.ini).



How to scan all drives to find directories which contain nothing but some of those files?







find






share|improve this question









New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 9 hours ago









Christopher

11.6k4 gold badges34 silver badges52 bronze badges




11.6k4 gold badges34 silver badges52 bronze badges






New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 9 hours ago









Rami SedhomRami Sedhom

1396 bronze badges




1396 bronze badges




New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • 1





    Do you actually need to find the directories, or are you just going to delete those useless files and the directories? In the second case, you could just first delete the useless files, and then delete all now-empty directories. (Which would of course also remove any directories that were empty to begin with.)

    – ilkkachu
    7 hours ago













  • 1





    Do you actually need to find the directories, or are you just going to delete those useless files and the directories? In the second case, you could just first delete the useless files, and then delete all now-empty directories. (Which would of course also remove any directories that were empty to begin with.)

    – ilkkachu
    7 hours ago








1




1





Do you actually need to find the directories, or are you just going to delete those useless files and the directories? In the second case, you could just first delete the useless files, and then delete all now-empty directories. (Which would of course also remove any directories that were empty to begin with.)

– ilkkachu
7 hours ago






Do you actually need to find the directories, or are you just going to delete those useless files and the directories? In the second case, you could just first delete the useless files, and then delete all now-empty directories. (Which would of course also remove any directories that were empty to begin with.)

– ilkkachu
7 hours ago











5 Answers
5






active

oldest

votes


















4














To find all directories that contain no other name than *.tmp, desktop.ini, Thumbs.db, and/or .picasa.ini:



find . -type d -exec bash -O dotglob -c '
for dirpath do
ok=true
seen_files=false
set -- "$dirpath"/*
for name do
[ -d "$name" ] && continue # skip dirs
seen_files=true
case "$name##*/" in
*.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
*) ok=false; break
esac
done

"$seen_files" && "$ok" && printf "%sn" "$dirpath"
done' bash +


This would use find to locate any directories beneath the current directory (including the current directory) and pass them to a shell script.



The shell script iterates over the given directory paths, and for each, it expands * in it (with the dotglob shell option set in bash to catch hidden names).



It then goes through the list of resulting names and matches them against the particular patterns and names that we'd like to find (ignoring directories). If it finds any other name that doesn't match our list, it sets ok to false (from having been true) and breaks out of that inner loop.



The seen_files variable becomes true as soon as we've seen a file. This variable helps us avoid reporting subdirectories that only contain other subdirectories.



It then runs $seen_files and $ok (true or false) and if these are both true, which means that the directory contains at least one regular file, and only contains filenames in our list, it prints the pathname of the directory.



Instead of



set -- "$dirpath"/*
for name do


you could obviously do



for name in "$dirpath"/*; do


instead.



Testing:



$ tree
.
`-- dir
|-- Thumbs.db
`-- dir
|-- file.tmp
`-- something

2 directories, 3 files


(find command is run here, producing the output...)



./dir


This means that the directory ./dir only contains names in the list (ignoring directories), while ./dir/dir contains other things as well.



If you remove [ -d "$name" ] && continue from the code, the ./dir directory would not have been found since it contains a name (dir) that is not in our list.






share|improve this answer



























  • That fails to return empty directories (you'd probably want nullglob as well).

    – Stéphane Chazelas
    7 hours ago











  • That returns directories that have only subdirs which I doubt is what the OP wants.

    – Stéphane Chazelas
    7 hours ago











  • @StéphaneChazelas Empty directories do not have any files matching any of those names, so that's ok. The second issue will be fixed later in the evening (I'm busy).

    – Kusalananda
    7 hours ago






  • 1





    But they contain nothing but some of those files. OK, the requirements are a bit ambiguous, and I suppose your interpretation makes more sense than mine. I've updated my answer with both options.

    – Stéphane Chazelas
    7 hours ago











  • @StéphaneChazelas Worked around the subdirs-only issue.

    – Kusalananda
    2 hours ago


















3














You would need to specify the files or folders, ideally by name, like:



find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty rm


will find all files (-type f) called (-iname) "thumbs.db" (ignoring case because of the i in iname) and then removing (rm) them.



You may use filename patterns, e.g.



find $HOME -type f -iname '*.tmp' -print0 | xargs -0 --no-run-if-empty rm


Warning: Please be careful what you type, deleting may happen without asking you.



Do make regular backups - right before getting to work on your cleanup may be a good moment!



If you wish to find out what would happen look at the file list first before rming anything, like:



find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty ls -l





share|improve this answer



























  • It just list all paths/thumb.db but those paths may contain other files. I just need to list directories that contain only this file and nothing else.

    – Rami Sedhom
    9 hours ago











  • So for every directory out of find, it may count files & sub-directories, if it's 1, then print, otherwise ignore.

    – Rami Sedhom
    9 hours ago











  • Your code will find the pathnames to those files (and delete them, even though this was not part of the question), but it does not actually find the directories that contains only these files.

    – Kusalananda
    8 hours ago











  • @Kusalananda I did not realise it was that important. I would personally go in afterwards and find ~ -type d -print0 | xargs -0 --no-run rmdir -p but only (of course) if there are no other empty folders.

    – Ned64
    8 hours ago












  • @Ned64 thanks for your answer, it inspired me to find my answer :)

    – Rami Sedhom
    8 hours ago


















2














Used this combination of find, xargs, ls, sed, wc and awk commands and it is working:



find . -type f ( -iname "desktop.ini" -o -name "thumb.db" ) -printf %h\0 | xargs -0 -I "" sh -c 'printf "t"; ls -l "" | sed -n "1!p" | wc -l' | awk '$2 == "1" print $0'


Explanation:




  • find . find in current directory


  • -type f find files only


  • ( -iname "desktop.ini" -o -name "thumb.db" )where filename is "desktop.ini" or "thumb.db" case insensitive


  • printf %h\0 print leading directory of file's name + ASCII NUL


  • xargs -0 -I "" sh -c 'printf "t"; ls -l "" print output directory and execute ls -l on each one


  • sed -n "1!p" | wc -l' exclude first line of ls -l which contain total files and directories and then count lines


  • awk '$2 == "1" print $0' print line if only count is equal to "1"





share|improve this answer










New contributor



Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 2





    Never embed the in the shell code, that's very dangerous and makes it an arbitrary code injection vulnerability and is not portable (think of a directory called $(reboot) for instance).

    – Stéphane Chazelas
    7 hours ago






  • 2





    The first argument of printf is the format, you shouldn't use variable data in there.

    – Stéphane Chazelas
    7 hours ago






  • 2





    You use -printf %h\0 and xargs -0 (GNU extensions btw), but they treat file names as if they were lines or words.

    – Stéphane Chazelas
    7 hours ago






  • 2





    Effectively, it seems the intention of that code is to report directories that contain only one entry and that one entry being either desktop.ini or thumbs.db which is different from your requirements in your question.

    – Stéphane Chazelas
    7 hours ago






  • 2





    Note that sed -n '1!p' can be written tail -n +2.

    – Stéphane Chazelas
    7 hours ago


















2














With zsh, you can do



set -o extendedglob
printf '%sn' **/*(D/^e'[()(($#)) $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND)]')


To list the directories that do not contain entries other than (*.tmp|desktop.ini|Thumbs.db|.picasa.ini) ones, so would report empty directories and directories containing only this kind of entries.




  • **/: recursive glob (any level of subdirectories)


  • *(qualifier): glob (here * matching any file), with qualifiers (to match on other criteria than name).


  • D: enable dotglob for that glob (include hidden files and look inside hidden dirs).


  • /: only select files of type directory


  • ^: negate the following qualifiers


  • e'[code]': an evaluation qualifier: select the files for which the code does not (with the previous ^) return true.


  • () code args: anonymous function. Here the code is (($#)) which is a ksh-style arithmetic expression which here evaluates to true if $# is non-zero ($# being the number of arguments to the anonymous function).


  • $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND) makes up the arguments to that inline function. Here that's another glob:


  • $REPLY: inside the e'[code]' that's the path to the file currently being considered.


  • ^: negation (that's the operator for which we need extendeglob).


  • (*.tmp|desktop.ini|Thumbs.db|.picasa.ini): either of those, so with negation, none of those. You can prefix it with (#i) if you want case-insensitive matching.


  • (ND): another glob qualifier. N for nullglob (the glob expands to nothing if there's no match, so (($#)) becomes false), D for dotglob again.

If you don't want to include empty directories, add the F glob qualifier (for Full)






share|improve this answer



























  • would you add a little explanation

    – Rami Sedhom
    8 hours ago











  • @RamiSedhom, see edit.

    – Stéphane Chazelas
    7 hours ago


















2














With GNU find and GNU awk, you could have find report all the files and awk do the matching:



find . -depth -type d -printf '%p/' -o -printf '%p' |
gawk -F/ -v OFS=/ -v RS='' -v IGNORECASE=1 '
//$/
NF--
if (good[$0] == 0 && bad[$0] > 0) print
next

.picasa.ini)/)
bad[$0]++
else
good[$0]++
'


If you also want to include the empty directories, remove the && bad[$0] > 0. If if you want case sensitive matching, remove -v IGNORECASE=1.






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',
    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
    );



    );






    Rami Sedhom is a new contributor. Be nice, and check out our Code of Conduct.









    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535364%2fhow-to-find-directories-containing-only-specific-files%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    To find all directories that contain no other name than *.tmp, desktop.ini, Thumbs.db, and/or .picasa.ini:



    find . -type d -exec bash -O dotglob -c '
    for dirpath do
    ok=true
    seen_files=false
    set -- "$dirpath"/*
    for name do
    [ -d "$name" ] && continue # skip dirs
    seen_files=true
    case "$name##*/" in
    *.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
    *) ok=false; break
    esac
    done

    "$seen_files" && "$ok" && printf "%sn" "$dirpath"
    done' bash +


    This would use find to locate any directories beneath the current directory (including the current directory) and pass them to a shell script.



    The shell script iterates over the given directory paths, and for each, it expands * in it (with the dotglob shell option set in bash to catch hidden names).



    It then goes through the list of resulting names and matches them against the particular patterns and names that we'd like to find (ignoring directories). If it finds any other name that doesn't match our list, it sets ok to false (from having been true) and breaks out of that inner loop.



    The seen_files variable becomes true as soon as we've seen a file. This variable helps us avoid reporting subdirectories that only contain other subdirectories.



    It then runs $seen_files and $ok (true or false) and if these are both true, which means that the directory contains at least one regular file, and only contains filenames in our list, it prints the pathname of the directory.



    Instead of



    set -- "$dirpath"/*
    for name do


    you could obviously do



    for name in "$dirpath"/*; do


    instead.



    Testing:



    $ tree
    .
    `-- dir
    |-- Thumbs.db
    `-- dir
    |-- file.tmp
    `-- something

    2 directories, 3 files


    (find command is run here, producing the output...)



    ./dir


    This means that the directory ./dir only contains names in the list (ignoring directories), while ./dir/dir contains other things as well.



    If you remove [ -d "$name" ] && continue from the code, the ./dir directory would not have been found since it contains a name (dir) that is not in our list.






    share|improve this answer



























    • That fails to return empty directories (you'd probably want nullglob as well).

      – Stéphane Chazelas
      7 hours ago











    • That returns directories that have only subdirs which I doubt is what the OP wants.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Empty directories do not have any files matching any of those names, so that's ok. The second issue will be fixed later in the evening (I'm busy).

      – Kusalananda
      7 hours ago






    • 1





      But they contain nothing but some of those files. OK, the requirements are a bit ambiguous, and I suppose your interpretation makes more sense than mine. I've updated my answer with both options.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Worked around the subdirs-only issue.

      – Kusalananda
      2 hours ago















    4














    To find all directories that contain no other name than *.tmp, desktop.ini, Thumbs.db, and/or .picasa.ini:



    find . -type d -exec bash -O dotglob -c '
    for dirpath do
    ok=true
    seen_files=false
    set -- "$dirpath"/*
    for name do
    [ -d "$name" ] && continue # skip dirs
    seen_files=true
    case "$name##*/" in
    *.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
    *) ok=false; break
    esac
    done

    "$seen_files" && "$ok" && printf "%sn" "$dirpath"
    done' bash +


    This would use find to locate any directories beneath the current directory (including the current directory) and pass them to a shell script.



    The shell script iterates over the given directory paths, and for each, it expands * in it (with the dotglob shell option set in bash to catch hidden names).



    It then goes through the list of resulting names and matches them against the particular patterns and names that we'd like to find (ignoring directories). If it finds any other name that doesn't match our list, it sets ok to false (from having been true) and breaks out of that inner loop.



    The seen_files variable becomes true as soon as we've seen a file. This variable helps us avoid reporting subdirectories that only contain other subdirectories.



    It then runs $seen_files and $ok (true or false) and if these are both true, which means that the directory contains at least one regular file, and only contains filenames in our list, it prints the pathname of the directory.



    Instead of



    set -- "$dirpath"/*
    for name do


    you could obviously do



    for name in "$dirpath"/*; do


    instead.



    Testing:



    $ tree
    .
    `-- dir
    |-- Thumbs.db
    `-- dir
    |-- file.tmp
    `-- something

    2 directories, 3 files


    (find command is run here, producing the output...)



    ./dir


    This means that the directory ./dir only contains names in the list (ignoring directories), while ./dir/dir contains other things as well.



    If you remove [ -d "$name" ] && continue from the code, the ./dir directory would not have been found since it contains a name (dir) that is not in our list.






    share|improve this answer



























    • That fails to return empty directories (you'd probably want nullglob as well).

      – Stéphane Chazelas
      7 hours ago











    • That returns directories that have only subdirs which I doubt is what the OP wants.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Empty directories do not have any files matching any of those names, so that's ok. The second issue will be fixed later in the evening (I'm busy).

      – Kusalananda
      7 hours ago






    • 1





      But they contain nothing but some of those files. OK, the requirements are a bit ambiguous, and I suppose your interpretation makes more sense than mine. I've updated my answer with both options.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Worked around the subdirs-only issue.

      – Kusalananda
      2 hours ago













    4












    4








    4







    To find all directories that contain no other name than *.tmp, desktop.ini, Thumbs.db, and/or .picasa.ini:



    find . -type d -exec bash -O dotglob -c '
    for dirpath do
    ok=true
    seen_files=false
    set -- "$dirpath"/*
    for name do
    [ -d "$name" ] && continue # skip dirs
    seen_files=true
    case "$name##*/" in
    *.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
    *) ok=false; break
    esac
    done

    "$seen_files" && "$ok" && printf "%sn" "$dirpath"
    done' bash +


    This would use find to locate any directories beneath the current directory (including the current directory) and pass them to a shell script.



    The shell script iterates over the given directory paths, and for each, it expands * in it (with the dotglob shell option set in bash to catch hidden names).



    It then goes through the list of resulting names and matches them against the particular patterns and names that we'd like to find (ignoring directories). If it finds any other name that doesn't match our list, it sets ok to false (from having been true) and breaks out of that inner loop.



    The seen_files variable becomes true as soon as we've seen a file. This variable helps us avoid reporting subdirectories that only contain other subdirectories.



    It then runs $seen_files and $ok (true or false) and if these are both true, which means that the directory contains at least one regular file, and only contains filenames in our list, it prints the pathname of the directory.



    Instead of



    set -- "$dirpath"/*
    for name do


    you could obviously do



    for name in "$dirpath"/*; do


    instead.



    Testing:



    $ tree
    .
    `-- dir
    |-- Thumbs.db
    `-- dir
    |-- file.tmp
    `-- something

    2 directories, 3 files


    (find command is run here, producing the output...)



    ./dir


    This means that the directory ./dir only contains names in the list (ignoring directories), while ./dir/dir contains other things as well.



    If you remove [ -d "$name" ] && continue from the code, the ./dir directory would not have been found since it contains a name (dir) that is not in our list.






    share|improve this answer















    To find all directories that contain no other name than *.tmp, desktop.ini, Thumbs.db, and/or .picasa.ini:



    find . -type d -exec bash -O dotglob -c '
    for dirpath do
    ok=true
    seen_files=false
    set -- "$dirpath"/*
    for name do
    [ -d "$name" ] && continue # skip dirs
    seen_files=true
    case "$name##*/" in
    *.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
    *) ok=false; break
    esac
    done

    "$seen_files" && "$ok" && printf "%sn" "$dirpath"
    done' bash +


    This would use find to locate any directories beneath the current directory (including the current directory) and pass them to a shell script.



    The shell script iterates over the given directory paths, and for each, it expands * in it (with the dotglob shell option set in bash to catch hidden names).



    It then goes through the list of resulting names and matches them against the particular patterns and names that we'd like to find (ignoring directories). If it finds any other name that doesn't match our list, it sets ok to false (from having been true) and breaks out of that inner loop.



    The seen_files variable becomes true as soon as we've seen a file. This variable helps us avoid reporting subdirectories that only contain other subdirectories.



    It then runs $seen_files and $ok (true or false) and if these are both true, which means that the directory contains at least one regular file, and only contains filenames in our list, it prints the pathname of the directory.



    Instead of



    set -- "$dirpath"/*
    for name do


    you could obviously do



    for name in "$dirpath"/*; do


    instead.



    Testing:



    $ tree
    .
    `-- dir
    |-- Thumbs.db
    `-- dir
    |-- file.tmp
    `-- something

    2 directories, 3 files


    (find command is run here, producing the output...)



    ./dir


    This means that the directory ./dir only contains names in the list (ignoring directories), while ./dir/dir contains other things as well.



    If you remove [ -d "$name" ] && continue from the code, the ./dir directory would not have been found since it contains a name (dir) that is not in our list.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 2 hours ago

























    answered 8 hours ago









    KusalanandaKusalananda

    159k18 gold badges316 silver badges502 bronze badges




    159k18 gold badges316 silver badges502 bronze badges















    • That fails to return empty directories (you'd probably want nullglob as well).

      – Stéphane Chazelas
      7 hours ago











    • That returns directories that have only subdirs which I doubt is what the OP wants.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Empty directories do not have any files matching any of those names, so that's ok. The second issue will be fixed later in the evening (I'm busy).

      – Kusalananda
      7 hours ago






    • 1





      But they contain nothing but some of those files. OK, the requirements are a bit ambiguous, and I suppose your interpretation makes more sense than mine. I've updated my answer with both options.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Worked around the subdirs-only issue.

      – Kusalananda
      2 hours ago

















    • That fails to return empty directories (you'd probably want nullglob as well).

      – Stéphane Chazelas
      7 hours ago











    • That returns directories that have only subdirs which I doubt is what the OP wants.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Empty directories do not have any files matching any of those names, so that's ok. The second issue will be fixed later in the evening (I'm busy).

      – Kusalananda
      7 hours ago






    • 1





      But they contain nothing but some of those files. OK, the requirements are a bit ambiguous, and I suppose your interpretation makes more sense than mine. I've updated my answer with both options.

      – Stéphane Chazelas
      7 hours ago











    • @StéphaneChazelas Worked around the subdirs-only issue.

      – Kusalananda
      2 hours ago
















    That fails to return empty directories (you'd probably want nullglob as well).

    – Stéphane Chazelas
    7 hours ago





    That fails to return empty directories (you'd probably want nullglob as well).

    – Stéphane Chazelas
    7 hours ago













    That returns directories that have only subdirs which I doubt is what the OP wants.

    – Stéphane Chazelas
    7 hours ago





    That returns directories that have only subdirs which I doubt is what the OP wants.

    – Stéphane Chazelas
    7 hours ago













    @StéphaneChazelas Empty directories do not have any files matching any of those names, so that's ok. The second issue will be fixed later in the evening (I'm busy).

    – Kusalananda
    7 hours ago





    @StéphaneChazelas Empty directories do not have any files matching any of those names, so that's ok. The second issue will be fixed later in the evening (I'm busy).

    – Kusalananda
    7 hours ago




    1




    1





    But they contain nothing but some of those files. OK, the requirements are a bit ambiguous, and I suppose your interpretation makes more sense than mine. I've updated my answer with both options.

    – Stéphane Chazelas
    7 hours ago





    But they contain nothing but some of those files. OK, the requirements are a bit ambiguous, and I suppose your interpretation makes more sense than mine. I've updated my answer with both options.

    – Stéphane Chazelas
    7 hours ago













    @StéphaneChazelas Worked around the subdirs-only issue.

    – Kusalananda
    2 hours ago





    @StéphaneChazelas Worked around the subdirs-only issue.

    – Kusalananda
    2 hours ago













    3














    You would need to specify the files or folders, ideally by name, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty rm


    will find all files (-type f) called (-iname) "thumbs.db" (ignoring case because of the i in iname) and then removing (rm) them.



    You may use filename patterns, e.g.



    find $HOME -type f -iname '*.tmp' -print0 | xargs -0 --no-run-if-empty rm


    Warning: Please be careful what you type, deleting may happen without asking you.



    Do make regular backups - right before getting to work on your cleanup may be a good moment!



    If you wish to find out what would happen look at the file list first before rming anything, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty ls -l





    share|improve this answer



























    • It just list all paths/thumb.db but those paths may contain other files. I just need to list directories that contain only this file and nothing else.

      – Rami Sedhom
      9 hours ago











    • So for every directory out of find, it may count files & sub-directories, if it's 1, then print, otherwise ignore.

      – Rami Sedhom
      9 hours ago











    • Your code will find the pathnames to those files (and delete them, even though this was not part of the question), but it does not actually find the directories that contains only these files.

      – Kusalananda
      8 hours ago











    • @Kusalananda I did not realise it was that important. I would personally go in afterwards and find ~ -type d -print0 | xargs -0 --no-run rmdir -p but only (of course) if there are no other empty folders.

      – Ned64
      8 hours ago












    • @Ned64 thanks for your answer, it inspired me to find my answer :)

      – Rami Sedhom
      8 hours ago















    3














    You would need to specify the files or folders, ideally by name, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty rm


    will find all files (-type f) called (-iname) "thumbs.db" (ignoring case because of the i in iname) and then removing (rm) them.



    You may use filename patterns, e.g.



    find $HOME -type f -iname '*.tmp' -print0 | xargs -0 --no-run-if-empty rm


    Warning: Please be careful what you type, deleting may happen without asking you.



    Do make regular backups - right before getting to work on your cleanup may be a good moment!



    If you wish to find out what would happen look at the file list first before rming anything, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty ls -l





    share|improve this answer



























    • It just list all paths/thumb.db but those paths may contain other files. I just need to list directories that contain only this file and nothing else.

      – Rami Sedhom
      9 hours ago











    • So for every directory out of find, it may count files & sub-directories, if it's 1, then print, otherwise ignore.

      – Rami Sedhom
      9 hours ago











    • Your code will find the pathnames to those files (and delete them, even though this was not part of the question), but it does not actually find the directories that contains only these files.

      – Kusalananda
      8 hours ago











    • @Kusalananda I did not realise it was that important. I would personally go in afterwards and find ~ -type d -print0 | xargs -0 --no-run rmdir -p but only (of course) if there are no other empty folders.

      – Ned64
      8 hours ago












    • @Ned64 thanks for your answer, it inspired me to find my answer :)

      – Rami Sedhom
      8 hours ago













    3












    3








    3







    You would need to specify the files or folders, ideally by name, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty rm


    will find all files (-type f) called (-iname) "thumbs.db" (ignoring case because of the i in iname) and then removing (rm) them.



    You may use filename patterns, e.g.



    find $HOME -type f -iname '*.tmp' -print0 | xargs -0 --no-run-if-empty rm


    Warning: Please be careful what you type, deleting may happen without asking you.



    Do make regular backups - right before getting to work on your cleanup may be a good moment!



    If you wish to find out what would happen look at the file list first before rming anything, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty ls -l





    share|improve this answer















    You would need to specify the files or folders, ideally by name, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty rm


    will find all files (-type f) called (-iname) "thumbs.db" (ignoring case because of the i in iname) and then removing (rm) them.



    You may use filename patterns, e.g.



    find $HOME -type f -iname '*.tmp' -print0 | xargs -0 --no-run-if-empty rm


    Warning: Please be careful what you type, deleting may happen without asking you.



    Do make regular backups - right before getting to work on your cleanup may be a good moment!



    If you wish to find out what would happen look at the file list first before rming anything, like:



    find $HOME -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty ls -l






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 9 hours ago

























    answered 9 hours ago









    Ned64Ned64

    3,2341 gold badge16 silver badges42 bronze badges




    3,2341 gold badge16 silver badges42 bronze badges















    • It just list all paths/thumb.db but those paths may contain other files. I just need to list directories that contain only this file and nothing else.

      – Rami Sedhom
      9 hours ago











    • So for every directory out of find, it may count files & sub-directories, if it's 1, then print, otherwise ignore.

      – Rami Sedhom
      9 hours ago











    • Your code will find the pathnames to those files (and delete them, even though this was not part of the question), but it does not actually find the directories that contains only these files.

      – Kusalananda
      8 hours ago











    • @Kusalananda I did not realise it was that important. I would personally go in afterwards and find ~ -type d -print0 | xargs -0 --no-run rmdir -p but only (of course) if there are no other empty folders.

      – Ned64
      8 hours ago












    • @Ned64 thanks for your answer, it inspired me to find my answer :)

      – Rami Sedhom
      8 hours ago

















    • It just list all paths/thumb.db but those paths may contain other files. I just need to list directories that contain only this file and nothing else.

      – Rami Sedhom
      9 hours ago











    • So for every directory out of find, it may count files & sub-directories, if it's 1, then print, otherwise ignore.

      – Rami Sedhom
      9 hours ago











    • Your code will find the pathnames to those files (and delete them, even though this was not part of the question), but it does not actually find the directories that contains only these files.

      – Kusalananda
      8 hours ago











    • @Kusalananda I did not realise it was that important. I would personally go in afterwards and find ~ -type d -print0 | xargs -0 --no-run rmdir -p but only (of course) if there are no other empty folders.

      – Ned64
      8 hours ago












    • @Ned64 thanks for your answer, it inspired me to find my answer :)

      – Rami Sedhom
      8 hours ago
















    It just list all paths/thumb.db but those paths may contain other files. I just need to list directories that contain only this file and nothing else.

    – Rami Sedhom
    9 hours ago





    It just list all paths/thumb.db but those paths may contain other files. I just need to list directories that contain only this file and nothing else.

    – Rami Sedhom
    9 hours ago













    So for every directory out of find, it may count files & sub-directories, if it's 1, then print, otherwise ignore.

    – Rami Sedhom
    9 hours ago





    So for every directory out of find, it may count files & sub-directories, if it's 1, then print, otherwise ignore.

    – Rami Sedhom
    9 hours ago













    Your code will find the pathnames to those files (and delete them, even though this was not part of the question), but it does not actually find the directories that contains only these files.

    – Kusalananda
    8 hours ago





    Your code will find the pathnames to those files (and delete them, even though this was not part of the question), but it does not actually find the directories that contains only these files.

    – Kusalananda
    8 hours ago













    @Kusalananda I did not realise it was that important. I would personally go in afterwards and find ~ -type d -print0 | xargs -0 --no-run rmdir -p but only (of course) if there are no other empty folders.

    – Ned64
    8 hours ago






    @Kusalananda I did not realise it was that important. I would personally go in afterwards and find ~ -type d -print0 | xargs -0 --no-run rmdir -p but only (of course) if there are no other empty folders.

    – Ned64
    8 hours ago














    @Ned64 thanks for your answer, it inspired me to find my answer :)

    – Rami Sedhom
    8 hours ago





    @Ned64 thanks for your answer, it inspired me to find my answer :)

    – Rami Sedhom
    8 hours ago











    2














    Used this combination of find, xargs, ls, sed, wc and awk commands and it is working:



    find . -type f ( -iname "desktop.ini" -o -name "thumb.db" ) -printf %h\0 | xargs -0 -I "" sh -c 'printf "t"; ls -l "" | sed -n "1!p" | wc -l' | awk '$2 == "1" print $0'


    Explanation:




    • find . find in current directory


    • -type f find files only


    • ( -iname "desktop.ini" -o -name "thumb.db" )where filename is "desktop.ini" or "thumb.db" case insensitive


    • printf %h\0 print leading directory of file's name + ASCII NUL


    • xargs -0 -I "" sh -c 'printf "t"; ls -l "" print output directory and execute ls -l on each one


    • sed -n "1!p" | wc -l' exclude first line of ls -l which contain total files and directories and then count lines


    • awk '$2 == "1" print $0' print line if only count is equal to "1"





    share|improve this answer










    New contributor



    Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.
















    • 2





      Never embed the in the shell code, that's very dangerous and makes it an arbitrary code injection vulnerability and is not portable (think of a directory called $(reboot) for instance).

      – Stéphane Chazelas
      7 hours ago






    • 2





      The first argument of printf is the format, you shouldn't use variable data in there.

      – Stéphane Chazelas
      7 hours ago






    • 2





      You use -printf %h\0 and xargs -0 (GNU extensions btw), but they treat file names as if they were lines or words.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Effectively, it seems the intention of that code is to report directories that contain only one entry and that one entry being either desktop.ini or thumbs.db which is different from your requirements in your question.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Note that sed -n '1!p' can be written tail -n +2.

      – Stéphane Chazelas
      7 hours ago















    2














    Used this combination of find, xargs, ls, sed, wc and awk commands and it is working:



    find . -type f ( -iname "desktop.ini" -o -name "thumb.db" ) -printf %h\0 | xargs -0 -I "" sh -c 'printf "t"; ls -l "" | sed -n "1!p" | wc -l' | awk '$2 == "1" print $0'


    Explanation:




    • find . find in current directory


    • -type f find files only


    • ( -iname "desktop.ini" -o -name "thumb.db" )where filename is "desktop.ini" or "thumb.db" case insensitive


    • printf %h\0 print leading directory of file's name + ASCII NUL


    • xargs -0 -I "" sh -c 'printf "t"; ls -l "" print output directory and execute ls -l on each one


    • sed -n "1!p" | wc -l' exclude first line of ls -l which contain total files and directories and then count lines


    • awk '$2 == "1" print $0' print line if only count is equal to "1"





    share|improve this answer










    New contributor



    Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.
















    • 2





      Never embed the in the shell code, that's very dangerous and makes it an arbitrary code injection vulnerability and is not portable (think of a directory called $(reboot) for instance).

      – Stéphane Chazelas
      7 hours ago






    • 2





      The first argument of printf is the format, you shouldn't use variable data in there.

      – Stéphane Chazelas
      7 hours ago






    • 2





      You use -printf %h\0 and xargs -0 (GNU extensions btw), but they treat file names as if they were lines or words.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Effectively, it seems the intention of that code is to report directories that contain only one entry and that one entry being either desktop.ini or thumbs.db which is different from your requirements in your question.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Note that sed -n '1!p' can be written tail -n +2.

      – Stéphane Chazelas
      7 hours ago













    2












    2








    2







    Used this combination of find, xargs, ls, sed, wc and awk commands and it is working:



    find . -type f ( -iname "desktop.ini" -o -name "thumb.db" ) -printf %h\0 | xargs -0 -I "" sh -c 'printf "t"; ls -l "" | sed -n "1!p" | wc -l' | awk '$2 == "1" print $0'


    Explanation:




    • find . find in current directory


    • -type f find files only


    • ( -iname "desktop.ini" -o -name "thumb.db" )where filename is "desktop.ini" or "thumb.db" case insensitive


    • printf %h\0 print leading directory of file's name + ASCII NUL


    • xargs -0 -I "" sh -c 'printf "t"; ls -l "" print output directory and execute ls -l on each one


    • sed -n "1!p" | wc -l' exclude first line of ls -l which contain total files and directories and then count lines


    • awk '$2 == "1" print $0' print line if only count is equal to "1"





    share|improve this answer










    New contributor



    Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.









    Used this combination of find, xargs, ls, sed, wc and awk commands and it is working:



    find . -type f ( -iname "desktop.ini" -o -name "thumb.db" ) -printf %h\0 | xargs -0 -I "" sh -c 'printf "t"; ls -l "" | sed -n "1!p" | wc -l' | awk '$2 == "1" print $0'


    Explanation:




    • find . find in current directory


    • -type f find files only


    • ( -iname "desktop.ini" -o -name "thumb.db" )where filename is "desktop.ini" or "thumb.db" case insensitive


    • printf %h\0 print leading directory of file's name + ASCII NUL


    • xargs -0 -I "" sh -c 'printf "t"; ls -l "" print output directory and execute ls -l on each one


    • sed -n "1!p" | wc -l' exclude first line of ls -l which contain total files and directories and then count lines


    • awk '$2 == "1" print $0' print line if only count is equal to "1"






    share|improve this answer










    New contributor



    Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.








    share|improve this answer



    share|improve this answer








    edited 8 hours ago





















    New contributor



    Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.








    answered 8 hours ago









    Rami SedhomRami Sedhom

    1396 bronze badges




    1396 bronze badges




    New contributor



    Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.




    New contributor




    Rami Sedhom is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.












    • 2





      Never embed the in the shell code, that's very dangerous and makes it an arbitrary code injection vulnerability and is not portable (think of a directory called $(reboot) for instance).

      – Stéphane Chazelas
      7 hours ago






    • 2





      The first argument of printf is the format, you shouldn't use variable data in there.

      – Stéphane Chazelas
      7 hours ago






    • 2





      You use -printf %h\0 and xargs -0 (GNU extensions btw), but they treat file names as if they were lines or words.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Effectively, it seems the intention of that code is to report directories that contain only one entry and that one entry being either desktop.ini or thumbs.db which is different from your requirements in your question.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Note that sed -n '1!p' can be written tail -n +2.

      – Stéphane Chazelas
      7 hours ago












    • 2





      Never embed the in the shell code, that's very dangerous and makes it an arbitrary code injection vulnerability and is not portable (think of a directory called $(reboot) for instance).

      – Stéphane Chazelas
      7 hours ago






    • 2





      The first argument of printf is the format, you shouldn't use variable data in there.

      – Stéphane Chazelas
      7 hours ago






    • 2





      You use -printf %h\0 and xargs -0 (GNU extensions btw), but they treat file names as if they were lines or words.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Effectively, it seems the intention of that code is to report directories that contain only one entry and that one entry being either desktop.ini or thumbs.db which is different from your requirements in your question.

      – Stéphane Chazelas
      7 hours ago






    • 2





      Note that sed -n '1!p' can be written tail -n +2.

      – Stéphane Chazelas
      7 hours ago







    2




    2





    Never embed the in the shell code, that's very dangerous and makes it an arbitrary code injection vulnerability and is not portable (think of a directory called $(reboot) for instance).

    – Stéphane Chazelas
    7 hours ago





    Never embed the in the shell code, that's very dangerous and makes it an arbitrary code injection vulnerability and is not portable (think of a directory called $(reboot) for instance).

    – Stéphane Chazelas
    7 hours ago




    2




    2





    The first argument of printf is the format, you shouldn't use variable data in there.

    – Stéphane Chazelas
    7 hours ago





    The first argument of printf is the format, you shouldn't use variable data in there.

    – Stéphane Chazelas
    7 hours ago




    2




    2





    You use -printf %h\0 and xargs -0 (GNU extensions btw), but they treat file names as if they were lines or words.

    – Stéphane Chazelas
    7 hours ago





    You use -printf %h\0 and xargs -0 (GNU extensions btw), but they treat file names as if they were lines or words.

    – Stéphane Chazelas
    7 hours ago




    2




    2





    Effectively, it seems the intention of that code is to report directories that contain only one entry and that one entry being either desktop.ini or thumbs.db which is different from your requirements in your question.

    – Stéphane Chazelas
    7 hours ago





    Effectively, it seems the intention of that code is to report directories that contain only one entry and that one entry being either desktop.ini or thumbs.db which is different from your requirements in your question.

    – Stéphane Chazelas
    7 hours ago




    2




    2





    Note that sed -n '1!p' can be written tail -n +2.

    – Stéphane Chazelas
    7 hours ago





    Note that sed -n '1!p' can be written tail -n +2.

    – Stéphane Chazelas
    7 hours ago











    2














    With zsh, you can do



    set -o extendedglob
    printf '%sn' **/*(D/^e'[()(($#)) $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND)]')


    To list the directories that do not contain entries other than (*.tmp|desktop.ini|Thumbs.db|.picasa.ini) ones, so would report empty directories and directories containing only this kind of entries.




    • **/: recursive glob (any level of subdirectories)


    • *(qualifier): glob (here * matching any file), with qualifiers (to match on other criteria than name).


    • D: enable dotglob for that glob (include hidden files and look inside hidden dirs).


    • /: only select files of type directory


    • ^: negate the following qualifiers


    • e'[code]': an evaluation qualifier: select the files for which the code does not (with the previous ^) return true.


    • () code args: anonymous function. Here the code is (($#)) which is a ksh-style arithmetic expression which here evaluates to true if $# is non-zero ($# being the number of arguments to the anonymous function).


    • $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND) makes up the arguments to that inline function. Here that's another glob:


    • $REPLY: inside the e'[code]' that's the path to the file currently being considered.


    • ^: negation (that's the operator for which we need extendeglob).


    • (*.tmp|desktop.ini|Thumbs.db|.picasa.ini): either of those, so with negation, none of those. You can prefix it with (#i) if you want case-insensitive matching.


    • (ND): another glob qualifier. N for nullglob (the glob expands to nothing if there's no match, so (($#)) becomes false), D for dotglob again.

    If you don't want to include empty directories, add the F glob qualifier (for Full)






    share|improve this answer



























    • would you add a little explanation

      – Rami Sedhom
      8 hours ago











    • @RamiSedhom, see edit.

      – Stéphane Chazelas
      7 hours ago















    2














    With zsh, you can do



    set -o extendedglob
    printf '%sn' **/*(D/^e'[()(($#)) $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND)]')


    To list the directories that do not contain entries other than (*.tmp|desktop.ini|Thumbs.db|.picasa.ini) ones, so would report empty directories and directories containing only this kind of entries.




    • **/: recursive glob (any level of subdirectories)


    • *(qualifier): glob (here * matching any file), with qualifiers (to match on other criteria than name).


    • D: enable dotglob for that glob (include hidden files and look inside hidden dirs).


    • /: only select files of type directory


    • ^: negate the following qualifiers


    • e'[code]': an evaluation qualifier: select the files for which the code does not (with the previous ^) return true.


    • () code args: anonymous function. Here the code is (($#)) which is a ksh-style arithmetic expression which here evaluates to true if $# is non-zero ($# being the number of arguments to the anonymous function).


    • $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND) makes up the arguments to that inline function. Here that's another glob:


    • $REPLY: inside the e'[code]' that's the path to the file currently being considered.


    • ^: negation (that's the operator for which we need extendeglob).


    • (*.tmp|desktop.ini|Thumbs.db|.picasa.ini): either of those, so with negation, none of those. You can prefix it with (#i) if you want case-insensitive matching.


    • (ND): another glob qualifier. N for nullglob (the glob expands to nothing if there's no match, so (($#)) becomes false), D for dotglob again.

    If you don't want to include empty directories, add the F glob qualifier (for Full)






    share|improve this answer



























    • would you add a little explanation

      – Rami Sedhom
      8 hours ago











    • @RamiSedhom, see edit.

      – Stéphane Chazelas
      7 hours ago













    2












    2








    2







    With zsh, you can do



    set -o extendedglob
    printf '%sn' **/*(D/^e'[()(($#)) $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND)]')


    To list the directories that do not contain entries other than (*.tmp|desktop.ini|Thumbs.db|.picasa.ini) ones, so would report empty directories and directories containing only this kind of entries.




    • **/: recursive glob (any level of subdirectories)


    • *(qualifier): glob (here * matching any file), with qualifiers (to match on other criteria than name).


    • D: enable dotglob for that glob (include hidden files and look inside hidden dirs).


    • /: only select files of type directory


    • ^: negate the following qualifiers


    • e'[code]': an evaluation qualifier: select the files for which the code does not (with the previous ^) return true.


    • () code args: anonymous function. Here the code is (($#)) which is a ksh-style arithmetic expression which here evaluates to true if $# is non-zero ($# being the number of arguments to the anonymous function).


    • $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND) makes up the arguments to that inline function. Here that's another glob:


    • $REPLY: inside the e'[code]' that's the path to the file currently being considered.


    • ^: negation (that's the operator for which we need extendeglob).


    • (*.tmp|desktop.ini|Thumbs.db|.picasa.ini): either of those, so with negation, none of those. You can prefix it with (#i) if you want case-insensitive matching.


    • (ND): another glob qualifier. N for nullglob (the glob expands to nothing if there's no match, so (($#)) becomes false), D for dotglob again.

    If you don't want to include empty directories, add the F glob qualifier (for Full)






    share|improve this answer















    With zsh, you can do



    set -o extendedglob
    printf '%sn' **/*(D/^e'[()(($#)) $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND)]')


    To list the directories that do not contain entries other than (*.tmp|desktop.ini|Thumbs.db|.picasa.ini) ones, so would report empty directories and directories containing only this kind of entries.




    • **/: recursive glob (any level of subdirectories)


    • *(qualifier): glob (here * matching any file), with qualifiers (to match on other criteria than name).


    • D: enable dotglob for that glob (include hidden files and look inside hidden dirs).


    • /: only select files of type directory


    • ^: negate the following qualifiers


    • e'[code]': an evaluation qualifier: select the files for which the code does not (with the previous ^) return true.


    • () code args: anonymous function. Here the code is (($#)) which is a ksh-style arithmetic expression which here evaluates to true if $# is non-zero ($# being the number of arguments to the anonymous function).


    • $REPLY/^(*.tmp|desktop.ini|Thumbs.db|.picasa.ini)(ND) makes up the arguments to that inline function. Here that's another glob:


    • $REPLY: inside the e'[code]' that's the path to the file currently being considered.


    • ^: negation (that's the operator for which we need extendeglob).


    • (*.tmp|desktop.ini|Thumbs.db|.picasa.ini): either of those, so with negation, none of those. You can prefix it with (#i) if you want case-insensitive matching.


    • (ND): another glob qualifier. N for nullglob (the glob expands to nothing if there's no match, so (($#)) becomes false), D for dotglob again.

    If you don't want to include empty directories, add the F glob qualifier (for Full)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 7 hours ago

























    answered 8 hours ago









    Stéphane ChazelasStéphane Chazelas

    329k57 gold badges641 silver badges1008 bronze badges




    329k57 gold badges641 silver badges1008 bronze badges















    • would you add a little explanation

      – Rami Sedhom
      8 hours ago











    • @RamiSedhom, see edit.

      – Stéphane Chazelas
      7 hours ago

















    • would you add a little explanation

      – Rami Sedhom
      8 hours ago











    • @RamiSedhom, see edit.

      – Stéphane Chazelas
      7 hours ago
















    would you add a little explanation

    – Rami Sedhom
    8 hours ago





    would you add a little explanation

    – Rami Sedhom
    8 hours ago













    @RamiSedhom, see edit.

    – Stéphane Chazelas
    7 hours ago





    @RamiSedhom, see edit.

    – Stéphane Chazelas
    7 hours ago











    2














    With GNU find and GNU awk, you could have find report all the files and awk do the matching:



    find . -depth -type d -printf '%p/' -o -printf '%p' |
    gawk -F/ -v OFS=/ -v RS='' -v IGNORECASE=1 '
    //$/
    NF--
    if (good[$0] == 0 && bad[$0] > 0) print
    next

    .picasa.ini)/)
    bad[$0]++
    else
    good[$0]++
    '


    If you also want to include the empty directories, remove the && bad[$0] > 0. If if you want case sensitive matching, remove -v IGNORECASE=1.






    share|improve this answer































      2














      With GNU find and GNU awk, you could have find report all the files and awk do the matching:



      find . -depth -type d -printf '%p/' -o -printf '%p' |
      gawk -F/ -v OFS=/ -v RS='' -v IGNORECASE=1 '
      //$/
      NF--
      if (good[$0] == 0 && bad[$0] > 0) print
      next

      .picasa.ini)/)
      bad[$0]++
      else
      good[$0]++
      '


      If you also want to include the empty directories, remove the && bad[$0] > 0. If if you want case sensitive matching, remove -v IGNORECASE=1.






      share|improve this answer





























        2












        2








        2







        With GNU find and GNU awk, you could have find report all the files and awk do the matching:



        find . -depth -type d -printf '%p/' -o -printf '%p' |
        gawk -F/ -v OFS=/ -v RS='' -v IGNORECASE=1 '
        //$/
        NF--
        if (good[$0] == 0 && bad[$0] > 0) print
        next

        .picasa.ini)/)
        bad[$0]++
        else
        good[$0]++
        '


        If you also want to include the empty directories, remove the && bad[$0] > 0. If if you want case sensitive matching, remove -v IGNORECASE=1.






        share|improve this answer















        With GNU find and GNU awk, you could have find report all the files and awk do the matching:



        find . -depth -type d -printf '%p/' -o -printf '%p' |
        gawk -F/ -v OFS=/ -v RS='' -v IGNORECASE=1 '
        //$/
        NF--
        if (good[$0] == 0 && bad[$0] > 0) print
        next

        .picasa.ini)/)
        bad[$0]++
        else
        good[$0]++
        '


        If you also want to include the empty directories, remove the && bad[$0] > 0. If if you want case sensitive matching, remove -v IGNORECASE=1.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 3 hours ago

























        answered 3 hours ago









        Stéphane ChazelasStéphane Chazelas

        329k57 gold badges641 silver badges1008 bronze badges




        329k57 gold badges641 silver badges1008 bronze badges























            Rami Sedhom is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded


















            Rami Sedhom is a new contributor. Be nice, and check out our Code of Conduct.












            Rami Sedhom is a new contributor. Be nice, and check out our Code of Conduct.











            Rami Sedhom is a new contributor. Be nice, and check out our Code of Conduct.














            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.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535364%2fhow-to-find-directories-containing-only-specific-files%23new-answer', 'question_page');

            );

            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







            Popular posts from this blog

            Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

            Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

            François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480