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
Commented
Jan 8, 2014 at 16:20
*
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'
Commented
Jan 8, 2014 at 18:55
locate will work as long as the directory is indexed. Otherwise use find
find /directory/to/search -name "*.txt" -exec ls -ld {} + >> result.txt
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.
Commented
Jan 8, 2014 at 16:22
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"