[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: find and copy



Thanks Zenaan, for moving this back on-list (to anyone interested, I replied
privately by mistake. Zenaan was gracious enough to accept my mistake)

On Wed, Sep 04, 2013 at 07:16:42AM +1000, Zenaan Harkness wrote:
> 
> It seems I was a bit cavalier on more than one count. My apologies.

No apology necessary. I was cranky that day, and I think we're good. You were
trying to help and that's more important to me.

> 
> > Actaully I considered xargs, but I am very lacking in knowledge
> > of it, and the man page did not offer a solution (that I could see)
> > either. Your suggestion included here will not work, nor will your
> > follow-up suggestion (although the suggestions are appreciated).
> 
> Actually, a bit of tweaking and it will work.

Of course. That's the beauty of an OS built on user desires. :)

> 
> > Both seem to be trying to copy the string '{}' and the directory
> > /var/data.backup/ to the directory name that is being piped to
> > xargs, the name of the found file in this case, which is how I
> > understand xargs to funtion. Regardless, I get the same error to
> > both:
> >
> >    "cp: target `dump_08-31-13.sql' is not a directory"
> 
> Ah yes, well then an argument to cp should do it:
> ... | xargs cp -t /var/data.backup/
> 
> ought to do the job. And you can test first with the following:
> ... | xargs echo cp -t /var/data.backup/
>             ^^^^

This works in that it copies the found files to /var/data.backup, but does not
rename it in the process. I'm on another system right now without PostgreSQL,
but my testing was as follows:
   mkdir /tmp/var
   mkdir /tmp/data.backup
   touch /tmp/var/test.sql
   find /tmp/var -mmin -60 -a -iname '*.sql' 2>/dev/null | \
      xargs echo cp -t /tmp/data.backup

which outputs this:
   cp -t /tmp/data.backup /tmp/var/test.sql

and then this (without the echo this time)
   find /tmp/var -mmin -60 -a -iname '*.sql' 2>/dev/null | \
      xargs cp -t /tmp/data.backup
   ls -l /tmp/data.backup/

outputs this:
   -rw-r--r--  1 craig craig    0 Sep  5 19:13 test.sql


Of course, being Linux, there is always yet another way (this without xargs):
   find /tmp/var -mmin -60 -a -iname '*.sql' -execdir \
      sh -c 'cp "$0" /tmp/data.backup/${HOSTNAME}".${0:2}"' {} \;
   ls -l /tmp/data.backup/

results in:
   -rw-r--r--  1 craig craig    0 Sep  5 19:14 craigbox.test.sql
   -rw-r--r--  1 craig craig    0 Sep  5 19:13 test.sql

The {} argument to sh is $0, and ${0:2} extracts the substring starting after
position 2, from the string represented by {} (./test.sql in this case). It
effectively strips the leading ./

Two caveats regarding that solution:
I have sh pointing to bash on my system. None of the above is tested using dash
which is the default shell on Debian these days. I would expect the same
results, but I am completely unfamiliar with dash.
And, I am pretty sure the sh spawns a subshell for each file found, so in my
case where I know there will only be up to three files it will take minimal
time and resources. I am unsure about the hit a large number of matches would
incur, especially if the files copied are large too.

Cheers,
Craig


Reply to: