Date: Wed, 9 Feb 2000 08:53:58 +0100 (CET) From: Oliver Fromme <olli@dorifer.heim3.tu-clausthal.de> To: freebsd-questions@FreeBSD.ORG Subject: Re: OFF TOPIC - Shell Script Question Message-ID: <200002090753.IAA48007@dorifer.heim3.tu-clausthal.de> In-Reply-To: <87q4gd$1gv1$1@atlantis.rz.tu-clausthal.de>
next in thread | previous in thread | raw e-mail | index | archive | help
Mark Ovens <mark@dogma.freebsd-uk.eu.org> wrote in list.freebsd-questions: > On Tue, Feb 08, 2000 at 02:34:25PM -0600, Darryl Hoar wrote: >> I have a directory with a ton of files in it. I need to move some of >> them to another >> directory. Here's what I'm thinking: >> >> ls -tl | grep '1999' | awk '{print "mv " $9 " /home/darryl/test"}' >> >> but it does not 'execute' the mv command. How do I get this cooking ? > > $ for i in `ls -lt | grep 1999 | awk '{print $9}'` Bad idea. If it's a "ton of files", it might overflow the maximum command line length. Darryl's first approach was better. To actually execute the commands (instead of just printing them to stdout, the output of the awk stage could pe simply piped into sh. Note that you can also integrate the grep as an awk pattern, saving a process and some overhead. Thus: ls -l | awk '/1999/{print "mv " $9 " /home/darryl/test"}' | sh Note, however, that there are a few possible problems. First, you probably want to match "1999" against the date of the file, but if the file is younger than 6 months, "ls -l" does not print the year. Use "ls -Tl" to always get a full time stamp output -- then $9 is the year (4 digits), and $10 is the file name. Second, the grep (and the awk pattern) match against the whole line. So if (for example) the size happens to contain the digits "1999", it matches, too -- this is probably not desired. Therefore it's better to check _only_ the column which contains the year numbers: ls -Tl | awk '($9==1999){print "mv " $10 " /home/darryl/test"}' | sh Finally, the above will break if a filename happens to contain special characters, such as spaces and quotes. This is more difficult to work around, but probably not worth the effort if you can avoid such filenames. By the way (off topic): Actually this job of moving files would be a very typical use of the xargs command, which is more efficient, but the problem is that the "mv" command expects the destination directory as the last argument. Therefore, I wrote a small shell script for myself, which takes the destination directory as the _first_ argument, and then a number of files to move: #!/bin/sh - DEST="$1"; shift; exec /bin/mv "$@" "$DEST" Calling that script "vm" (rev of "mv"), the problem could be solved like this: ls -Tl | awk '($9==1999){print $10}' | xargs vm /home/darryl/test The big advantage of this, of course, is that the mv command will be called for multiple files at once, while the first solution exec's a mv command for every single file to move, which is terribly inefficient, especially if there are a ton of them... (For the same reason, the -exec primary of the "find" command is evil and should not be used in general -- use xargs instead.) Regards Oliver -- Oliver Fromme, Leibnizstr. 18/61, 38678 Clausthal, Germany (Info: finger userinfo:olli@dorifer.heim3.tu-clausthal.de) "In jedem Stück Kohle wartet ein Diamant auf seine Geburt" (Terry Pratchett) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200002090753.IAA48007>