4

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?

4 Answers 4

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

should do the trick

4
  • 2
    Note using locate in this manner returns files that contain .txt anywhere in their names. For example: ...nginx/deployment_example.txt.erb.
    – slm
    Commented Jan 8, 2014 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 Commented Jan 8, 2014 at 16:20
  • @StephaneChazelas The leading * has no effect since locate assumes a leading and trailing * on the pattern.
    – doneal24
    Commented Jan 8, 2014 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' Commented Jan 8, 2014 at 18:55
4

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

find /directory/to/search -name "*.txt" -exec ls -ld {} + >> result.txt
3
  • With indexed you mean visible ?Like the result when using ls ?
    – Dan
    Commented Jan 8, 2014 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
    – Panther
    Commented Jan 8, 2014 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. Commented Jan 8, 2014 at 16:22
3

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.

3
  • 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
    Commented Jan 8, 2014 at 14:32
  • REPLY is the default name for each "line" if you don't specify a name.
    – l0b0
    Commented Jan 8, 2014 at 14:35
  • Ah, thanks, did not know about REPLY and thought that you meant the builtin command.
    – terdon
    Commented Jan 8, 2014 at 16:01
2

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"
1
  • @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.
    – doneal24
    Commented Jan 8, 2014 at 17:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .