GNU findutils doesn't find file - linux

When searching for .txt files that are in 2 different home directories only one shows up depending on the present working directory. Why is this?
/home/bob/1.txt
/home/alice/dir1/2.txt
pwd /tmp
[root#host tmp]#find /home -name *.txt
/home/bob/1.txt
/home/alice/dir1/2.txt
pwd /home
[root#host bob]#find /home -name *.txt
/home/bob/1.txt
Why does searching from within the bob directory only return the one file?

Why does searching from within the bob directory only return the one file?
Because when the working directory is /home/bob, the *.txt in the find command is expanded by the shell (to 1.txt) and that is what is passed to find. That is, find /home -name 1.txt. That will find the file in /home/bob, but not the differently named one in /home/alice. It would find /home/alice/1.txt if such a file existed.
On the other hand, when the pattern does not match any file (relative to the working directory) it is passed on as a literal. At least by default -- you should be careful about this, because the pattern would instead be expanded to nothing if the nullglob shell option were in effect and the find command were executed from a location where the pattern didn't match any files.
If you want to ensure that shell pathname expansion is not applied to the pattern then quote it:
find /home -name '*.txt'
or
find /home -name \*.txt
or ....

Related

copying files from etc ending with digit to test1 directory

I'm new to linux and as an exercice I need to copy the "etc" files that end with a digit from home directory to the test1 directory
(with one command).
I tried this but it dosn't work
find /etc -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
this should work for your home directory files ending with digit
mv `ls . |grep -Eo "^.*[0-9]$"` your-directory
lets says in the current directory you have some files like ofjweifhwef9 or kfhiofeh8 ( files ending with digit)
so ls will list them.
this grep expression "^.*[0-9]$"` will find only files ending with digit. ( because in your home directory system wont allow to have a file like this "/etc/somefile123")
and then mv will move those files to your-directory
note :- if grep cannot find the files ending with number you will see an error ofcourse because mv needs 2 operands but since it wasn't there so error.
mv: missing destination file operand after './your-directory'
It is probably because /etc is a link in the system that you're using, and find doesn't seem to consider it a path until you add an extra / at the end. Try this instead:
find /etc/ -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
Notice the /etc/ instead of /etc. I get the same behavior on my Mac where /etc is a link to another directory.
Of course, also make sure that you have files which names end on a digit under the /etc/ directory tree. I have none in my mac. You should get some files when you run:
find /etc/ -type f -iname "*[3-9]"
If you don't, you don't have any files to copy. You may also try: find /etc/ to see all files under the directory tree.
Finally, you may want to add the option: -depth 1 if you only want to copy the files in the /etc/ directory, as opposed to all the files that match in the directory tree under /etc/.

copying all the .tar and .tar.bz2 file systems from all the sub-directories into another directory

Imagine that i have lots of sub-directory in a sub-directory in a directory I wanted to copy all the .tar and .tar.bz2 extension files from all the sub-directories into another directory.
I used
$find /home/apple/mango -name *.tar -exec cp {} ./kk \;
but it copies only once from a sub directory and stops , it doesn't find files which are in other sub directories or go inside a sub directories and find them.
I want to do it recursively
You may use:
find /home/apple/mango -name '*.tar*' -execdir cp {} /full/path/to/kk \;
Note how name pattern is quoted to avoid shell expansion even before find command executes.
In the absence of quoting *.tar is expanded to some file.tar which is present in current directory and find stop right there because file.tar is not found in sub directories. By quoting glob pattern we make sure that find command gets literal pattern to search the sub directories.

How can I find a file within a specific directory name?

So I need to find all files in /home/ with a file name of "options.php".
find . -name "options.php"
When 'in home', that will find all options.php files, however, I want to only find all options.php files when they are in /public_html/.
So in other words, it should ignore all other 'options.php' files found.
eg, positive/show results:
/home/usr1/public_html/options.php
/home/usr2/public_html/options.php
eg, shouldnt show me:
/home/usr1/public_html/wp-admin/options.php
/home/usr2/public_html/wp-content/plugins/whatever/options.php
You can pass a pattern via -path option as follows:
find /home/ -path '*/public_html/options.php'
For a more flexible pattern use -regex which accepts a regular expression applied on the whole path. But in this particular case -regex has no advantage over -path:
find /home/ -regex '.*/public_html/options.php'
Filter the desired results from the found results with grep.
find . -name "options.php" | grep 'public_html/options.php'
You can limit the depth of find:
find . -maxdepth N, this way It should only find options.php in your desired folder.
The ls utility is much better suited for this task:
ls -1 /home/*/public_html/options.php
If you want to process the result list and do not want to have an error message or warning in case no such files are found, then simply redirect the error output of the command:
ls -1 /home/*/public_html/options.php 2>/dev/null
An alternative using the find utility would be:
find /home -path "*/public_html/options.php"
Or, if you want to prevent matches in folders called "public_html" further down in the hierarchy:
find /home -path "/home/*/public_html/options.php"
find /home -maxdepth 3 -path "*/public_html/options.php"

How to get a bare, recursive directory listing in Linux, excluding some directories

I need to obtain a recursive directory listing in Linux with only the directory and file name. It needs to include all files including hidden files with the exception of files name “.svn”.
I have tried multiple combinations of the “ls” command and haven’t been able to figure it out. When using “ls –R direname/ grep –v /$” I get a directory heading followed by a colon, which I cannot use.
If I have a directory name test with files and a sub-directory named test2 with files, I need the output to look like the following:
test
test/.filehidden1
test/file2
test/file3.txt
test/test2.log
test/test2/file.hidden1
test/test2/file2.boo
test/test2/file3.boo2
Notice there is no leading forward slash
find . -name .svn -prune -o -print
-prune tells it to not descend into any matching directories.
This should do:
find . ! -path \*.svn\*
This tells find to recursively list all files from . whose pathname does not contains .svn. This is not perfect since it may hide for instance file foo.svnbar.
Something like this:
find DIRNAME ! -name .svn
I need to obtain a recursive directory listing in Linux with only the directory and file name. It needs to include all files including hidden files with the exception of files name “.svn”.
Do you want to get a list of files in a Subversion repository?
This will do just that:
svn ls -R
If not, then you can use find:
find . ! -path '*/.svn/*' ! -name .svn
You mentioned "Notice there is no leading forward slash".
If that's very important, then the find command can be rephrased as:
find * .[^.]* ! -path '.svn/*' ! -name .svn

how do i find all files with the same name in all subdirectories

I want to find all the different .gitignore files I have to combine them into one.
I tried something like find */**/.gitignore but that came up with nothing.
All the files are in sub directories of my current dir, as well as the current directory.
I am using Bash on linux
find -name .gitignore
That should do
Since you are using bash:
shopt -s globstar
echo **/.gitignore
From man bash:
globstar
If set, the pattern ** used in a pathname expansion context will match a
files and zero or more directories and subdirectories. If the pattern is
followed by a /, only directories and subdirectories match.
Try this
find /home/user1 -name 'result.out' 2>/dev/null
In your case
find /<your DIR> -name '*.gitignore' 2>/dev/null
This results in
/home/user1/result.out
/home/user1/dir1/result.out
/home/user1/dir2/result.out

Resources