How do I get the name of a folder from a linux find commnad.
I have a command like this:
find /root/wgetlog -name -type d -empty
Whic produces the following results:
/root/wgetlog/smil3
/root/wgetlog/smil5
/root/wgetlog/smil4
how do I get just the name of the folder:
Example:
smil3
smil4
smil5
find /root/wgetlog -type d -empty -printf "%f\n"
If all you need is a relative path, then
{ pushd /root/wgetlog/; find . -name -type d -empty; popd; }
is the approach, especially if you do care about subdirectories of /root/wgetlog/*.
Use basename:
find /root/wgetlog -type d -empty -exec basename {} \;
You don't need -name.
You could also use sed to filter out the leading elements of each path:
$ find /usr/bin -type d
/usr/bin
/usr/bin/multiarch-i386-linux
/usr/bin/multiarch-x86_64-linux
/usr/bin/gda_trml2pdf
/usr/bin/gda_trml2html
...
$ find /usr/bin -type d | sed 's|.*/||'
bin
multiarch-i386-linux
multiarch-x86_64-linux
gda_trml2pdf
gda_trml2html
...
This might be more portable than using the -printf option of find, although that should not be an issue if you stick to Linux.
Disclaimer: this will fail horribly if you have newlines in your file/folder names. On the other hand, this snippet is probably not the only thing that would fail in that case...
Related
I have a find string that finds all the instances of a particular filename in a path, like so:
find /opt/logs* -type f -name "deploy.log" -exec ls {} \;
I need to return the result with 'FINENAME=' prepended on each line. Having a hard time figuring the best way.
find /opt/logs* -type f -name deploy.log | sed 's/^/FILENAME=/'
Note that if you have a directory named /opt/logs (and you're not trying to look in /opt/logs-foo/ and /opt/logs-date, or the like) you can drop the * and write find /opt/logs -type ...
Use the -printf option:
find /opt/logs* -type f -name "deploy.log" -printf='FILENAME=%p\n'
%p will get expanded to the file's name.
I would like to recursively find all files contained into a directory that has name “name1” or name “name2”
for instance:
structure/of/dir/name1/file1.a
structure/of/dir/name1/file2.b
structure/of/dir/name1/file3.c
structure/of/dir/name1/subfolder/file1s.a
structure/of/dir/name1/subfolder/file2s.b
structure/of/dir/name2/file1.a
structure/of/dir/name2/file2.b
structure/of/dir/name2/file3.c
structure/of/dir/name2/subfolder/file1s.a
structure/of/dir/name2/subfolder/file2s.b
structure/of/dir/name3/name1.a ←this should not show up in the result
structure/of/dir/name3/name2.a ←this should not show up in the result
so when I start my magic command the expected output should be this and only this:
structure/of/dir/name1/file1.a
structure/of/dir/name1/file2.b
structure/of/dir/name1/file3.c
structure/of/dir/name2/file1.a
structure/of/dir/name2/file2.b
structure/of/dir/name2/file3.c
I scripted something but it does not work because it search within the files and not only folder names:
for entry in $(find $SEARCH_DIR -type f | grep 'name1\|name2');
do
echo "FileName: $(basename $entry)"
done
If you can use the -regex option, avoiding subfolders with [^/]:
~$ find . -type f -regex ".*name1/[^/]*" -o -regex ".*name2/[^/]*"
./structure/of/dir/name2/file1.a
./structure/of/dir/name2/file3.c
./structure/of/dir/name2/subfolder
./structure/of/dir/name2/file2.b
./structure/of/dir/name1/file1.a
./structure/of/dir/name1/file3.c
./structure/of/dir/name1/file2.b
I'd use -path and -prune for this, since it's standard (unlike -regex which is GNU specific).
find . \( -path "*/name1/*" -o -path "*/name2/*" \) -prune -type f -print
But more importantly, never do for file in $(find...). Use finds -exec or a while read loop instead, depending on what you really need to with the matching files. See UsingFind and BashFAQ 20 for more on how to handle find safely.
Following is the folder structure
- home/ABCD/test1/example1/sample1/textfile.txt
If I execute the find command like
find /home/ABCD/ -type f -print
I am getting the following output
/home/ABCD/test1/example1/sample1/textfile.txt
Note: I am executing the find command from the ABCD folder, In the results I want to exclude /home/ABCD/ folder I just want /test1/example1/sample1/testfile.txt as the result
How can I achieve this?
Since you are executing find from /home/ABCD/ do something like this:
find * -type f -print
Or if you are looking for files in test1 do this:
find test1 -type f -print
Also with -maxdepth N you can limit the recursion in find
If you only want to look for files named textfile.txt do
find test1 -type f -name 'textfile.txt' -print
If you want to print the leading slash do
find . -type f -printf '/%p\n'
For more info have a look here
Note: If have the above string in a variable, you can trim it like this:
string="/home/ABCD/test1/example1/sample1/textfile.txt"
echo "${string#/home/ABCD}"
Some more examples of string manipulation here
Just use . as the starting directory
find . -type f -print
gives
./test1/example1/sample1/textfile.txt
and if you really want a leading slash, use -printf for the output
find . -type f -printf '/%P\n'
You can use the mindepth parameter to start looking at one level below the current directory
find /home/ABCD/ -mindepth 1 -type f -print
This should substitute your current working directory name with a .
find . -type f | perl -pne "s#$PWD#.#"
So you would get results like:
./test1/example1/sample1/textfile.txt
If you do not want the preceeding ./, use this command instead:
find . -type f | perl -pne "s#$PWD/##"
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.
I use Emacs and it sometimes makes backup for edited files. After a few days, I would have a lot of backup files whose name ends with a tilde.
Is there a way to find these files and delete them at once?
I tried this:
find "*" -type f -iname *~
But it doesn't work. I want the command to work recursively – something like ls -alR.
You need to escape from the shell. And you need to specify search path, not *
find . -type f -name '*~'
To delete the files:
find . -type f -name '*~' -exec rm -f '{}' \;
You can do something like that :
find . -type f -name '*~' -delete
If you want to delete also #*# file :
find . -type f -name '*~' -o -name '#*#' -delete
You can print all deleted files with "-print":
find . -type f -name '*~' -delete -print
Another way is by using grep.
lnydex99uhc:javastuff user$ ls
Permutation.java VigenereCipher.java VigenereCipher.java~
lnydex99uhc:javastuff user $ find . | grep .~$
./VigenereCipher.java~
You can also pass any command you want like this :
lnydex99uhc:javastuff zatef$ rm $(find . | grep .~$)