From owner-freebsd-questions@FreeBSD.ORG Tue Feb 17 07:56:37 2004 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BD8C316A4CE for ; Tue, 17 Feb 2004 07:56:37 -0800 (PST) Received: from tomts5-srv.bellnexxia.net (tomts5.bellnexxia.net [209.226.175.25]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6ED5C43D1F for ; Tue, 17 Feb 2004 07:56:37 -0800 (PST) (envelope-from dlavigne6@sympatico.ca) Received: from genisis ([64.230.83.103]) by tomts5-srv.bellnexxia.net (InterMail vM.5.01.06.05 201-253-122-130-105-20030824) with ESMTP id <20040217155632.JAHC108.tomts5-srv.bellnexxia.net@genisis>; Tue, 17 Feb 2004 10:56:32 -0500 Date: Tue, 17 Feb 2004 11:00:07 -0500 (EST) From: Dru X-X-Sender: dlavigne6@genisis.domain.org To: Erik Trulsson In-Reply-To: <20040217154814.GA46529@falcon.midgard.homeip.net> Message-ID: <20040217105935.D629@genisis.domain.org> References: <20040216163818.R609@genisis.domain.org> <20040217100421.R629@genisis.domain.org> <20040217154814.GA46529@falcon.midgard.homeip.net> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: questions@freebsd.org Subject: Re: copying files with same name X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Feb 2004 15:56:37 -0000 On Tue, 17 Feb 2004, Erik Trulsson wrote: > On Tue, Feb 17, 2004 at 10:16:18AM -0500, Dru wrote: > > On Mon, 16 Feb 2004, Erik Trulsson wrote: > > > > > On Mon, Feb 16, 2004 at 04:49:37PM -0500, Dru wrote: > > > > > > > > Okay, I must be missing something obvious here. How do you do a batch copy > > > > while renaming the destination files? I want to copy all of the configure > > > > scripts in /usr/ports to ~/scripts. I can get find to find the files, I > > > > can get sed to rename them, but I can't get the timing down right. > > > > > > > > cp -v `find /usr/ports -name configure -print | sed 's:/:=:g'` . > > > > > > > > renames the files nicely (so they're not all named configure), but does it > > > > too soon--the source no longer exists. > > > > > > > > cp -v `find /usr/ports -name configure -print -exec sed 's:/:=:g' {} \;` . > > > > > > > > gives a syntax error (missing }) and > > > > > > > > cp -v `find /usr/ports -name configure -print | sed 's:/:=:g'` . > > > > > > > > has sed complain of extra characters at the end of a p command, followed > > > > by all my destination files being named configure. > > > > > > > > Is there a way to do this as a one-liner, or does one have to write a > > > > shell script with a while loop? > > > > > > First you should note that there are two ways of using cp(1). > > > The first one is of teh form 'cp src-file dst-file' and the second one > > > is of the form 'cp src-file1 src-file2 src-file3 ... dstdir' > > > So if you don't want the dest-file to have the same name as the source, > > > you must invoke cp(1) once for each file. > > > > > > You will have to use some kind of loop to do this. A for loop iterating > > > over the output of find(1) would seem to be better suited for this > > > problem than a while loop. > > > > > > Well, I played some more and piping to cpio did the trick. I couldn't do > > it in one go as pass mode doesn't support the interactively rename switch, > > but a temporary copy out followed by an interactive copy in worked. > > > > I then tried pax -rwi which was even more efficient as it let me rename > > while find was creating the list. > > Doing the renaming interactively sounds a bit cumbersome if there are > many files. > > The following for-loop ought to do the trick nicely and doesn't require > any interactive actions: > (Assuming you have want to name the destination files as your examples > above indicate, and also assuming you want to copy the files to the > current directory.) > > for i in `find /usr/ports -name configure -print` > do > cp $i ./`echo $i | sed 's:/:=:g'` > done > > > You could either put that in a shell-script or type it in directly at > the commandline. It works with both /bin/sh and zsh, and ought to work > with bash and ksh as well. > > The above for-loop is actually a bit inefficient since it doesn't > start to do any copying until after find has found all the files to be > copied, and this can also give a very long command-line after the > expansion of find's output which might cause trouble. > > An better alternative is to do the copying as find(1) goes down the > tree with something like the following one-liner: > > find /usr/ports -name configure -exec sh -c 'cp {} `echo {} | sed s:/:=:g`' \; Thanks. This one and Peder's accomplish the exact same thing :-) Dru