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: