On Tue, Apr 19, 2022 at 7:00 AM Rich Shepard <rshep...@appl-ecosys.com>
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

Reply via email to