On Tue, Apr 19, 2022 at 7:00 AM Rich Shepard <[email protected]>
wrote:
> On Mon, 18 Apr 2022, Michael Barnes wrote:
>
> > Now I want to copy all those files into a new directory. I've tried
> > various combinations of pipe to something, but no joy.
>
> Michael,
>
> I'm not as knowledgable as Russell or Galen but your question interests me
> so I looked on my Slackware system's locate man page. Slackware uses
> slocate, the secure version of GNU's locate command.
>
> Most options refer to the databases to be searched; there is no -0 option,
> but there is -i. More to the point of your question is this option:
> -o <file>
> --output=<file> Specfies the database to create.
> I interpret this option as allowing you to create a file with the output of
> the locate command's results.
>
> That written, on my system I can use the standard output redirection
> symbol,
> '>' to write locate's output to a file. I tested this by:
> locate stormwater > temp.out
> and the temp.out file contains 112 files with that string in their name;
> examples:
> /data1/eis-examples/rosemont-cu/figures/storm-water/barrel_stormwater.shp
>
> /data1/eis-examples/rosemont-cu/figures/storm-water/barrel_stormwater.shp.xml
> /data1/eis-examples/rosemont-cu/figures/storm-water/mpo_stormwater.shp
> /data1/eis-examples/rosemont-cu/figures/storm-water/barrel_stormwater.shx
> /data1/eis-examples/rosemont-cu/figures/storm-water/phased_stormwater.shx
> /data1/eis-examples/rosemont-cu/figures/storm-water/mpo_stormwater.sbn
> /data1/eis-examples/rosemont-cu/figures/storm-water/mpo_stormwater.prj
>
> Woiks for me. :-)
>
It sounds like this is a question about copying a list of files rather than
about using locate. Locate just happens to be the method of generating the
list, but the list could be generated by anything: find, ls, tar, unzip,
whatever.
My personal preference when given a list is to use xargs, but any looping
structure would work: for, while, until. To borrow and expand on previous
examples:
$ locate -0 -i bozo | xargs -0 cp -t /tmp/fiz/
However, using `cp` creates a challenge with two edge cases:
1) files with the same name in two different directories. For example,
imagine these items in the list:
/foo/bar/bozo.txt
/biz/bot/bozo.txt
2) directories. For example, imagine this item in the list:
/foo/bar/bozo/
That second item may or may not be an issue, depending on how the list was
generated. From what I've read `locate` does not report directories, but
that may depend on the version or implementation[1].
One possible solution to the first issue is to use rsync with the -R option
and modify the list using sed and tr. For example,
<< 'eof' sed -e 's#/#/./#2' | tr '\n' '\0' | xargs -0 -iSRC echo rsync -R
SRC /tmp/fiz/
/foo/bar/bozo.txt
/biz/bot/bozo.txt
eof
The `sed` command replaces the second slash with a /./, which rsync -R uses
as a directory anchor.
The `tr` replaces the newline with the null character, which xargs -0 uses
to handle any filenames that contain spaces.
The `echo` is so that you can view the resulting commands, which look like
this:
rsync -R /foo/./bar/bozo.txt /tmp/fiz/
rsync -R /biz/./bot/bozo.txt /tmp/fiz/
If you remove the `echo`, the result would be this hierarchy:
$ tree /tmp/fiz/
/tmp/fiz/
├── bar
│ └── bozo.txt
└── bot
└── bozo.txt
rsync may also be a solution for the challenge with directories. You can
use the -r or -a option with rsync to recurse into directories.
Good luck and let us know how things go.
[1]
https://linux.die.net/man/5/mlocate.db#:~:text=only%20reports%20file%20entries
Regards,
- Robert