Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have to search for a specific file type on a storage unit and also want to know their owners.

With locate '*.txt' >> result.txt I find all files I'm looking for but I'm missing the owner this way.

Any suggestions on how I could do it properly?

share|improve this question
add comment

4 Answers

up vote 5 down vote accepted
locate -0 '*.txt' | xargs -r0 stat -c "%n %U" >>result.txt

should do the trick

share|improve this answer
2  
Note using locate in this manner returns files that contain .txt anywhere in their names. For example: ...nginx/deployment_example.txt.erb. –  slm Jan 8 at 15:20
    
@slm, in the original question, there was *.txt (without the quotes), but the * was hidden because of SE formatting, so the question showed .txt –  Stephane Chazelas Jan 8 at 16:20
    
@StephaneChazelas The leading * has no effect since locate assumes a leading and trailing * on the pattern. –  Doug O'Neal Jan 8 at 17:27
    
@DougO'Neal no, locate assumes a leading and trailing * only if there's no wildcard character in the search string. So locate .txt is like locate '*.txt*' while locate '*.txt' is locate '*.txt' –  Stephane Chazelas Jan 8 at 18:55
add comment

locate will work as long as the directory is indexed. Otherwise use find

find /directory/to/search -name "*.txt" -exec ls -ld {} + >> result.txt
share|improve this answer
    
With indexed you mean visible ?Like the result when using ls ? –  Dan Jan 8 at 14:58
5  
No, the command "locate" uses a database to track files. The database is updated daily. You can manually update it with the command sudo updatedb, but the database does not include all system files and may not include removable devices depending on how you configured locate and if the device was connected when the database was last updated. See thegeekstuff.com/2012/03/locate-command-examples –  bodhi.zazen Jan 8 at 15:12
1  
Note that some find implementation have a -ls option to avoid executing ls. GNU find also has a -printf to output specific information like owner and path. –  Stephane Chazelas Jan 8 at 16:22
add comment

If you want it to handle file names with newlines and special characters in them, you'll want to output the user name first (since it can't contain special characters) and a NUL-separated list:

locate -0 .txt | xargs -r0 stat --printf "%U %n\0"

You can then process the files reliably:

while IFS=: read -r -d '' -u 9 user path
do
    whatever_you_want -- "$path"
done 9< <( locate -0 .txt | xargs -r0 stat --printf "%U:%n\0" )

The advantage over @DougONeal's answer is that it's easy to parse the result since the simple user name is first in the string, and since paths with newlines are handled correctly.

share|improve this answer
    
Don't you need to set $REPLY somewhere? And what is command doing there? As far as I can tell, it is attempting to run the $path, shouldn't that be an echo or printf? –  terdon Jan 8 at 14:32
    
REPLY is the default name for each "line" if you don't specify a name. –  l0b0 Jan 8 at 14:35
    
Ah, thanks, did not know about REPLY and thought that you meant the builtin command. –  terdon Jan 8 at 16:01
add comment

If you truly only want files that end in the suffix .txt the accepted answer will not do that. It will return results like this for example:

$ locate -0 .txt | xargs -r0 stat -c "%n %U" | grep -Ev '.txt '
...
/home/saml/.rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.4/lib/phusion_passenger/templates/apache2/run_installer_as_root.txt.erb saml
/home/saml/.rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.4/lib/phusion_passenger/templates/apache2/welcome.txt.erb saml
/home/saml/.rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.4/lib/phusion_passenger/templates/nginx/ask_for_extra_configure_flags.txt.erb saml
/home/saml/.rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.4/lib/phusion_passenger/templates/nginx/cannot_write_to_dir.txt.erb saml
/usr/share/vim/vim74/doc/usr_42.txt.gz root
...

Instead you can tell locate to use a regex instead like so:

$ locate -0 --regex '\.txt$' | xargs -r0 stat -c "%n %U"
share|improve this answer
    
@sim If you set the regex flag then you'll also have to escape the . in .txt - otherwise it will match any character. Files such as /usr/bin/ps2txt will show up. –  Doug O'Neal Jan 8 at 17:33
    
@DougO'Neal - thanks fixed. –  slm Jan 8 at 18:01
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.