- Find files in current directory non recursively linux
- Non-recursive way to list files in directory and subdirectories without using stack/queue
- Non-recursive way to get all files in a directory and its subdirectories in Java
- «find: paths must precede expression:» How do I specify a recursive search that also finds files in the current directory?
- Find empty directoris OR directories with no files in them recursively
- find not recursive when given a pattern on the command line
- 5 Answers 5
Find files in current directory non recursively linux
That’s rather slow, though, with the recursive s. A better solution might involve caching directories where files were found, or an approach that would start from empty directories and work up until a branch that contains file(s). But this approach very similar to stack/queue solution Solution 1: You can always replace a recursive solution with an iterative one by using a stack (for DFS) or a Queue (For BFS): Solution 2: Java 8 onward, you can use Files#walk to list out all files and directories recursively in a given directory.
Non-recursive way to list files in directory and subdirectories without using stack/queue
In a depth-first search note that the current path essentially serves as a stack. Listing names in a depth-first manner, proceed like you would expect but don’t bother recording a stack. When you’re done listing files in a directory, you can ‘pop’ the stack by noting what the last directory was that you were in and then continue from that point in the parent directory.
Try something like this (pseudocode):
baseDirectory = "/usr" list = [baseDirectory] // list of directories to traversal files = [] while (list not empty) < d = list.getFirst(); // get directory directories = ListDirectories(d); files.add(ListFiles(d)); // add all files from current directory list.add(directories); //add all directories from current directory to traversal list.remove(d); // remove traversed dir >
We using just lists 🙂 But this approach very similar to stack/queue solution
How to have ‘find’ not return the current directory, 2 Answers. Sorted by: 22. find returns the root path because it matches your criteria—i.e. it is a directory, and it doesn’t start with _. You’re looking for -mindepth 1, I suspect: $ cd /tmp $ mkdir a $ touch a/b $ mkdir a/c $ touch a/c/d $ find a a a/b a/c a/c/d $ find a -mindepth 1 a/b a/c a/c/d. Reference: find manpage.
Non-recursive way to get all files in a directory and its subdirectories in Java
You can always replace a recursive solution with an iterative one by using a stack (for DFS) or a Queue (For BFS):
private void printFiles(File dir) < Stackstack = new Stack(); stack.push(dir); while(!stack.isEmpty()) < File child = stack.pop(); if (child.isDirectory()) < for(File f : child.listFiles()) stack.push(f); >else if (child.isFile()) < System.out.println(child.getPath()); >> > printFiles(new File("abc/def.ghi"));
Java 8 onward, you can use Files#walk to list out all files and directories recursively in a given directory. Further you can apply the filter like Files::isRegularFile to filter out the directories if you need only regular files.
On the flip side, if you only need to list the given directory but not its sub-directories, you can use the lazy method Files#list which will only give you the files and directories in the given directory. You can again further apply the filter mentioned above.
FileUtils Is probably the best way to go. (COPY OF THE LINKED QUESTION) only posted so people searching this will see it and will probably not read the comments
edit: Methods to be used Listfiles
How to Delete Files Older Than 30 Days in Linux, As you can see in the figure above, there are two files and 2 directories older than 30 days. We can see files wpa.hash and wp-config.php, and wpascan and zmap directories.. The command below will remove files (No directories) in the specified path (As said, my path is LinuxHintDirectory located under the current path).. …
«find: paths must precede expression:» How do I specify a recursive search that also finds files in the current directory?
Try putting it in quotes — you’re running into the shell’s wildcard expansion, so what you’re acually passing to find will look like:
find . -name bobtest.c cattest.c snowtest.c
. causing the syntax error. So try this instead:
Note the single quotes around your file expression — these will stop the shell (bash) expanding your wildcards.
What’s happening is that the shell is expanding «*test.c» into a list of files. Try escaping the asterisk as:
How to Find Files and Folders in Linux Using the, The “find” command allows you to search for files for which you know the approximate filenames. The simplest form of the command searches for files in the current directory and recursively through its subdirectories that match the supplied search criteria. Y…
Find empty directoris OR directories with no files in them recursively
To see the directories deleted, just insert -print :
find . -type d -empty -print -delete
This would delete any sub-hierarchy beneath the current directory that is empty, while displaying the pathnames of the directories that are deleted.
The -delete action implies -depth , i.e. the traversal will start at the bottom of the directory structure and work its way up (a depth-first-traversal). This means that any directory that may be considered for deletion will already have its sub-directories processed (and these wil have been deleted if they were empty).
$ tree . `-- 1 `-- 2 `-- 3 `-- 4 `-- 5 `-- 6 6 directories, 0 file
$ find . -type d -empty -print -delete ./1/2/3/4/5/6 ./1/2/3/4/5 ./1/2/3/4 ./1/2/3 ./1/2 ./1
If one directory has a file:
$ tree . `-- 1 `-- 2 `-- 3 |-- 4 | `-- 5 | `-- 6 `-- file 6 directories, 1 file
$ find . -type d -empty -print -delete ./1/2/3/4/5/6 ./1/2/3/4/5 ./1/2/3/4
$ tree . `-- 1 `-- 2 `-- 3 `-- file 3 directories, 1 file
To list the directories that only contain subdirectories, but without deleting them (using bash ):
shopt -s globstar for dir in ./**/; do if [ -z "$(find "$dir" ! -type d -exec echo x \;)" ]; then printf '%s\n' "$dir" fi done
This would loop over all the subdirectories in the current directory (reclusively, using the ** shell glob), and then try to find something that is not a directory in any of them. If something is found, then that directory is not empty, otherwise the pathname of the empty directory is outputted.
With GNU find , you could add -quit to the very end of the above find command (after \; ) to speed things up a bit.
To print the empty directories without deleting any, we’ll have to do more than just remove the empty ones from the leaves up.
Something like this may work:
find dir/ -type d ! -exec sh -c \ 'find "$1" ! -type d -print -quit | grep -q . >/dev/null' sh <> \; -print
The outer find finds each directory, and runs another find on each of them. The inner find looks to see if that directory (recursively) contains any non-directories, and returns a true value if so. The outer find then prints each directory that returned false (i.e. didn’t contain any non-directories).
That’s rather slow, though, with the recursive find s. A better solution might involve caching directories where files were found, or an approach that would start from empty directories and work up until a branch that contains file(s).
Linux — How can I recursively find all files in current and, You could use «gpio*» to find all files who’s names start with gpio, or just «gpio1» to find all files named gpio1. – schumacher574 Apr 2, 2014 at 18:00 47 note that the «foo*» is in quotes so the shell doesn’t expand it before passing it to find. if you just did find . foo*, the foo* would be expanded AND THEN passed to … Usage examplefind . -name «foo*»Feedback
find not recursive when given a pattern on the command line
Imagine a source tree. There are xml files everywhere. But since there is a XYZ.xml at the root of this tree it won’t find my xml files.
./XYZ.xml ./a/b/c/bob.xml ./b/d/top.xml
From man find : Please note that you should quote patterns as a matter of course, otherwise the shell will expand any wildcard characters in them.
5 Answers 5
Otherwise, your shell expands *.xml to XYZ.xml , and the command that actually gets executed is
The reason it works if there are no XML files in the current directory is that shells generally leave wildcards unexpanded if they don’t match anything. In general, any time you want wildcards to be expanded by a program other than the shell (e.g. by find , tar , scp , etc.) you need to quote them so the shell won’t try to expand them itself.
Thx, that’s so simple, but I’ve been wondering how to get around that for months. I found that really weird, and to be a very inconsistent behavior, but now I understand since it’s not find, but bash’s fault.
It’s not bash’s «fault» per-se but yours for not quoting wildcards that you wanted to pass as arguments. This goes for all programs that accept shell input. The shell expands them as globs unless they are quoted or escaped.
You need to quote your argument like this:
so that it gets passed to find instead of being expanded by the shell, then passed to find as the expanded version.
Ok, so if *.xml doesn’t match anything in the current directory, it is passed on literally, which is why it works in the other case. Very helpful answer.
Wildcards are expanded by the shell, not by the command. find is one of the few commands that performs wildcard matching that’s similar to the shell, in its own time.
When you run ls *.xml , first the shell expands *.xml to the list of matching files, e.g. file1.xml file2.xml file3.xml , and then the shell calls ls with the resulting list of arguments file1.xml file2.xml file3.xml . That’s why you see the same list of file names with echo *.xml , even though echo knows nothing about files and doesn’t care whether its arguments are file names.
When you run find . -name «*.xml» :
- The shell parses the command line to recognize special characters and split it into words and puntuation. Here there’s just a list of words find , . , -name , *.xml where the * is quoted. Since * is quoted, it’s an ordinary character as far as the shell is concerned.
- The shell runs the command find with the specified list of arguments: . , -name , *.xml .
- find looks for files whose name matches the pattern *.xml in any directory under the current directory.
When you run find . -name *.xml and there are no files matching *.xml :
- The shell parses the command line to recognize special characters and split it into words and puntuation. Here there’s just a list of words find , . , -name , *.xml where the * is not quoted.
- Since the word *.xml contains an unquoted wildcard character, the shell performs filename generation. Since there are no matching file names, the pattern remains unexpanded.
- The shell runs the command find with the resulting list of arguments, which is . , -name , *.xml .
- find looks for files whose name matches the pattern *.xml in any directory under the current directory.
When you run find . -name *.xml and the current directory contains file1.xml , file2.xml and file3.xml :
- The shell parses the command line to recognize special characters and split it into words and puntuation. Here there’s just a list of words find , . , -name , *.xml where the * is not quoted.
- Since the word *.xml contains an unquoted wildcard character, the shell performs filename generation: *.xml is replaced by the list of matching file names.
- The shell runs the command find with the resulting list of arguments, which is . , -name , file1.xml , file2.xml , file3.xml .
- find complains about a syntax error when it reaches file2.xml .
When you run find . -name *.xml and the current directory contains a single matching file file.xml :
- The shell parses the command line to recognize special characters and split it into words and puntuation. Here there’s just a list of words find , . , -name , *.xml where the * is not quoted.
- Since the word *.xml contains an unquoted wildcard character, the shell performs filename generation: *.xml is replaced by the list of matching file names.
- The shell runs the command find with the resulting list of arguments, which is . , -name , file.xml .
- find sees a perfectly valid command, but it is probably not what you intended: find is told to look for files called file.xml in any directory, not to look for any file matching *.xml .
(Shell evaluation and expansion has a lot of other features. I only mentioned the ones that are relevant here.)
(What I describe is the default behavior of most common shells: sh, bash, dash, ksh, … Some shells can be configured to display an error instead of running a command with unexpanded wildcards, or to expand non-matching wildcards to an empty list. None of those would help here.)