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?
locate -0 '*.txt' | xargs -r0 stat -c "%n %U" >>result.txt
should do the trick
locate in this manner returns files that contain .txt anywhere in their names. For example: ...nginx/deployment_example.txt.erb.
*.txt (without the quotes), but the * was hidden because of SE formatting, so the question showed .txt
* has no effect since locate assumes a leading and trailing * on the pattern.
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'
locate will work as long as the directory is indexed. Otherwise use find
find /directory/to/search -name "*.txt" -exec ls -ld {} + >> result.txt
ls ?
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
find implementation have a -ls option to avoid executing ls. GNU find also has a -printf to output specific information like owner and path.
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.
$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?
REPLY is the default name for each "line" if you don't specify a name.
command.
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"