From owner-freebsd-questions@FreeBSD.ORG Tue Jun 5 02:32:45 2012 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 087881065686 for ; Tue, 5 Jun 2012 02:32:45 +0000 (UTC) (envelope-from vogelke@hcst.net) Received: from beta.hcst.com (beta.hcst.com [192.52.183.241]) by mx1.freebsd.org (Postfix) with ESMTP id A78388FC27 for ; Tue, 5 Jun 2012 02:32:44 +0000 (UTC) Received: from beta.hcst.com (localhost [127.0.0.1]) by beta.hcst.com (8.14.3/8.14.3/Debian-9.4) with ESMTP id q552RlDk027943 for ; Mon, 4 Jun 2012 22:27:47 -0400 Received: (from vogelke@localhost) by beta.hcst.com (8.14.3/8.14.3/Submit) id q552RljG027942; Mon, 4 Jun 2012 22:27:47 -0400 Received: by kev.msw.wpafb.af.mil (Postfix, from userid 32768) id 37C6CB7C1; Mon, 4 Jun 2012 22:26:49 -0400 (EDT) To: freebsd-questions@freebsd.org In-reply-to: (message from grarpamp on Sun, 3 Jun 2012 19:10:00 -0400) Organization: Array Infotech X-Disclaimer: I don't speak for the USAF or Array Infotech. X-GPG-ID: 1024D/711752A0 2006-06-27 Karl Vogel X-GPG-Fingerprint: 56EB 6DBF 4224 C953 F417 CC99 4C7C 7D46 7117 52A0 References: Message-Id: <20120605022649.37C6CB7C1@kev.msw.wpafb.af.mil> Date: Mon, 4 Jun 2012 22:26:49 -0400 (EDT) From: vogelke+unix@pobox.com (Karl Vogel) Subject: Re: /usr/bin/find - binary operands howto X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: vogelke+unix@pobox.com List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jun 2012 02:32:45 -0000 >> On Sun, 3 Jun 2012 19:10:00 -0400, >> grarpamp said: G> Given a fs with millions of inodes, multiple find runs is expensive. As G> is performing the ch* on more than the minimum required inodes, which G> also needlessly updates the inode ctime. So I want one find, doing the G> ch* only if necessary. So how should I write this? Do I want to use G> -true/-false somehow? It might be more efficient to keep find output in either a flat file or DB, so you can avoid multiple walks over the filetree. You'll need GNU find: #!/bin/sh export PATH=/usr/local/bin:/bin:/usr/bin test "$1" || set . echo '#filetype|inode|links|uname|gname|mode|size|mtime|pathname' gfind $@ -printf '%y|%i|%n|%u|%g|%m|%s|%T@|%p\n' exit 0 Sample output: root# chown 1234 stuff root# chgrp 5678 stuff me% ls -l drwxr-sr-x 3 kev local 512 04-Jun-2012 21:01:41 . drwxr-xr-x 2 kev local 512 04-Jun-2012 21:38:47 mail -rw-r--r-x 1 kev local 47072 04-Jun-2012 19:34:26 mail/junk* -rw-r--r-- 1 1234 5678 85 19-May-2012 23:28:30 stuff -rw-r--r-- 1 kev local 8104 04-Jun-2012 19:43:44 testing me% [run script] #filetype|inode|links|uname|gname|mode|size|mtime|pathname d|873603|3|kev|local|2755|512|1338858101|. d|1188634|2|kev|local|2755|512|1338860327|./mail f|1188649|1|kev|local|645|47072|1338852866|./mail/junk f|955452|1|1234|5678|644|85|1337484510|./stuff f|873708|1|kev|local|644|8104|1338853424|./testing Run this first, then look for the conditions you want using awk or perl. Advantages: * Doesn't change ctime, no additional filetree-walking. * You can use this to create your locate DB, if you want to avoid a second pass through the filesystem. * Gives you a point-in-time picture of ownership, mode, etc. in case you need to back out your changes. -- Karl Vogel I don't speak for the USAF or my company When I read about the evils of drinking, I gave up reading. --Henny Youngman