Show only directories, not their contents with `find -type d | xargs ls` - linux

I want to find some folders by name, and then list their information using "ls", here is what i did using "find",
find ./ -mindepth 1 -maxdepth 3 -type d -name logs
what i got is:
./RECHMN32Z/US/logs
./RECHMN32Z/UM/logs
./RECHMP3BL/US/logs
./RECHMP3BL/UM/logs
./RECHMAS86/UM/logs
./RECHMAS86/US/logs
and then i add "xargs ls -l" , then it will return information of all files under these folders returned above,
if i just want to list information of these folders, how to do ?

It's not find or xargs's fault, but ls's. When given directory names ls shows their contents. You can use -d to have it only show the directories themselves.
find has a -ls action that uses the same format as ls -dils. No need to invoke an external command.
find ./ -mindepth 1 -maxdepth 3 -type d -name logs -ls
Or use ls -ld to list the directories and not their contents. -exec cmd {} + is a simpler alternative to xargs. No pipeline required.
find ./ -mindepth 1 -maxdepth 3 -type d -name logs -exec ls -ld {} +

Related

Use Linux Find to search for directories that contain a file with properties

I'm trying to find projects in an enormous directory. The projects are always several levels of depth in and have a config file which contains the project name. So basically...
Given a path and string
Return any directory that has a depth of 3 from the and contains a file named "config"
that contains the
I learned that find combined with grep will work... but print out the grepped text and not the path of it's parent directory
find <starting-dir> -maxdepth 3 -mindepth 3 -type d -exec grep '<project-name>' {}/config \;
Just prints out the project name :(
Perhaps there any way to switch back to find's default behaviour of printing out the found file path only if the grep is successful? Or is there another tool I should try to use to solve this?
To get -print, you need to add it explicitly after a succesful -exec.
For example, using grep's -q:
find <starting-dir> \
-maxdepth 3 -mindepth 3 \
-type d \
-exec grep -q '<project-name>' {}/config \; \
-print
As you discovered, grep already has -l.
You can reduce the number of grep processes:
find <starting-dir> \
-maxdepth 4 -mindepth 4 \
-type f -name config \
-exec grep -l '<project-name>' {} +
Adding the -l flag to my output fixes the issue, for some reason I thought that would just print out "config" and not the whole path of that config file, but here we are.
find <starting-dir> -maxdepth 3 -mindepth 3 -type d -exec grep -l '<project-name>' {}/config \;
This will print out the full path of the config file of the project you search for.

How to list all the find -perm results?

I want to give a long list (with ls -l) of all the files in home directory that is writable by user, how can I combine find and ls -l?
find ~/ -maxdepth 1 -exec ls -l '{}' \;
If you are strictly interested only in files, i.e., no folders then you can tune the last command in the following way
find ~/ -maxdepth 1 -type f -exec ls -l '{}' \;
Check your man page for "find". It has a -ls action that you can tag on to the end:
-ls True; list current file in ls -dils format on standard output.

counting files in directory linux

Q2. Write a script that takes a directory name as command line argument and display the attributes of various files in it e.g.
Regular Files
Total No of files
No of directories
Files allowing write permissions
Files allowing read permissions
Files allowing execute permissions
File having size 0
Hidden files in directory
working in linux in shell script
what i have done is
find DIR_NAME -type f -print | wc -l
To count all files (including subdirs):
find /home/vivek -type f -print| wc -l
To count all dirs including subdirs:
find . -type d -print | wc -l
To only count files in given dir only (no subdir):
find /dest -maxdepth 1 -type f -print| wc -l
To only count dirs in given dir only (no subdir):
find /path/to/foo -maxdepth 1 -type d -print| wc -l
All your questions can be solved by looking into man find
-type f
no option necessary
-type d
-perm /u+w,g+w or some variation
-perm /u+r,g+r
-perm /u+x,g+x
-size 0
-name '.*'

pipe a command after splitting the returned value

I'm using a find command which results in multiple lines for result, I then want to pipe each of those lines into an ls command with the-l option specified.
find . -maxdepth 2 -type f |<some splitting method> | ls -l
I want to do this in one "command" and avoid writing to a file.
I believe this is what you are looking for:
find . -maxdepth 2 -type f -exec ls -l {} \;
Explanation:
find . -maxdepth 2 -type f: find files with maxdepth at 2
-exec ls -l {} \; For each such result found, run ls -l on it; {} specifies where the results from find would be substituted into.
The typical approach is to use -exec:
find . -maxdepth 2 -type f -exec ls -l {} \;
Sounds like you are looking for xargs. For example, on a typical Linux system:
find . -maxdepth 2 -type f -print0 | xargs -0 -n1 ls -l

find folders in a directory, without listing the parent directory

Having trouble listing the contents of a folder I'm not in, while excluding the actual folder name itself.
ex:
root#vps [~]# find ~/test -type d
/root/test
/root/test/test1
However I want it to only display /test1, as the example.
Thoughts?
There's nothing wrong with a simple
find ~/test -mindepth 1
Similarly, this will have the same effect:
find ~/test/*
as it matches everything contained within ~/test/ but not ~/test itself.
As an aside, you'll almost certainly find that find will complain about the -mindepth n option being after any other switches, as ordering is normally important but the -(min|max)depth n switches affect overall behaviour.
You can do that with -exec and basename:
find ~/test -type d -exec basename {} \;
Explanation:
The find ~/test -type d part finds all directories recursively under ~/test, as you already know.
The -exec basename {} \; part runs the basename command on {}, which is where all the results from the last step are substituted into.
Then you need -type f instead of -type d.
Or, if you want to display list of folders, excluding the parent -mindepth 1 (find ~/test -type d -mindepth 1).
And now that you edited it, I think what you want may be
find ~/test -type d -mindepth 1 |cut -d/ -f3-
But I think you need to be more specific ;-)
I just fixed it with sed
find $BASE -type d \( ! -iname "." \)|sed s/$BASE//g
Where $BASE is initial foldername.

Resources