zsh-users
 help / color / mirror / code / Atom feed
* script within find
@ 2007-02-24  7:39 Alexy Khrabrov
  2007-02-24 10:08 ` Stephane Chazelas
  0 siblings, 1 reply; 12+ messages in thread
From: Alexy Khrabrov @ 2007-02-24  7:39 UTC (permalink / raw)
  To: zsh-users

Here's a mystery solving which I've avoided for a while.  Now that I'm
going to publish a recipe for fixing Photoshop installation on a
case-sensitive Mac drive, I'd like to compress it into one script.

The problem is, the script contains a find command, which passes all
things it finds via -exec to a small helper script.  The helper script
is necessary since it seems difficult to make -exec contain a single
in-line command to do it.  Here they are:

-- the find command:

find . -name a -exec ~/bin/fix-ps-cs2.sh {} \;

-- the helper script, ~/bin/fix-ps-cs2.sh:

#!/bin/sh
DIR=`dirname $1`
(cd $DIR; ln -s a A)

as you see, it needs to invoke dirname on the argument, then create a
symlink in that dirname.

Can the helper script be avoided and all the work done within the
single find command?

Cheers,
Alexy


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-02-24  7:39 script within find Alexy Khrabrov
@ 2007-02-24 10:08 ` Stephane Chazelas
  2007-04-25 19:14   ` Alexy Khrabrov
  0 siblings, 1 reply; 12+ messages in thread
From: Stephane Chazelas @ 2007-02-24 10:08 UTC (permalink / raw)
  To: Alexy Khrabrov; +Cc: zsh-users

On Fri, Feb 23, 2007 at 11:39:40PM -0800, Alexy Khrabrov wrote:
> Here's a mystery solving which I've avoided for a while.  Now that I'm
> going to publish a recipe for fixing Photoshop installation on a
> case-sensitive Mac drive, I'd like to compress it into one script.
> 
> The problem is, the script contains a find command, which passes all
> things it finds via -exec to a small helper script.  The helper script
> is necessary since it seems difficult to make -exec contain a single
> in-line command to do it.  Here they are:
> 
> -- the find command:
> 
> find . -name a -exec ~/bin/fix-ps-cs2.sh {} \;
> 
> -- the helper script, ~/bin/fix-ps-cs2.sh:
> 
> #!/bin/sh
> DIR=`dirname $1`
> (cd $DIR; ln -s a A)
> 
> as you see, it needs to invoke dirname on the argument, then create a
> symlink in that dirname.
> 
> Can the helper script be avoided and all the work done within the
> single find command?
[...]

Not sure what that has to do with zsh, but on MAC OSX, I'd
expect find to have a -execdir:

find . -name a -execdir ln -s a A \;

Otherwise:

find . -name a -exec sh -c 'ln -s a "${1%a}A"' {} {} \;

-- 
Stéphane


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-02-24 10:08 ` Stephane Chazelas
@ 2007-04-25 19:14   ` Alexy Khrabrov
  2007-04-25 21:52     ` Chris Johnson
  0 siblings, 1 reply; 12+ messages in thread
From: Alexy Khrabrov @ 2007-04-25 19:14 UTC (permalink / raw)
  To: zsh-users

A while ago, Stephane suggested a terrific script on doing things
right inside find's exec.
I'm using that magic advice and it works, fantastic!  Still it's a bit
of a mystery to me.  Why do we need {} {} twice -- although there's
only one parameter reference to $1?

Also, how would I generalize it for two commands inside the script?
Here's an example.  I want to convert a bunch of .tif files to .jpg's.
 The original tifs reside in certain directory structure which should
be preserved in the target directory.

That is, we have something like

tifs/
  dir1/
    A.tif
    B.tif
  dir2/
    C.tif
  ...

And we need to create

jpgs/
  dir1/
    A.jpg
    B.jpg
  dir2/
    C.jpg
  ...

The command to do a single conversion is

convert -quality 100 dir1/A.tif /jpgs/dir1/A.jpg

-- however, we must ensure

mkdir -p /jpgs/`dirname {}` # or some such

-- before we invoke convert with the target path, to make sure it exists.

How can I stick *two* commands inside the exec in a find?

Cheers,
Alexy

On 2/24/07, Stephane Chazelas <Stephane_Chazelas@yahoo.fr> wrote:
> On Fri, Feb 23, 2007 at 11:39:40PM -0800, Alexy Khrabrov wrote:
> > Here's a mystery solving which I've avoided for a while.  Now that I'm
> > going to publish a recipe for fixing Photoshop installation on a
> > case-sensitive Mac drive, I'd like to compress it into one script.
> >
> > The problem is, the script contains a find command, which passes all
> > things it finds via -exec to a small helper script.  The helper script
> > is necessary since it seems difficult to make -exec contain a single
> > in-line command to do it.  Here they are:
> >
> > -- the find command:
> >
> > find . -name a -exec ~/bin/fix-ps-cs2.sh {} \;
> >
> > -- the helper script, ~/bin/fix-ps-cs2.sh:
> >
> > #!/bin/sh
> > DIR=`dirname $1`
> > (cd $DIR; ln -s a A)
> >
> > as you see, it needs to invoke dirname on the argument, then create a
> > symlink in that dirname.
> >
> > Can the helper script be avoided and all the work done within the
> > single find command?
> [...]
>
> Not sure what that has to do with zsh, but on MAC OSX, I'd
> expect find to have a -execdir:
>
> find . -name a -execdir ln -s a A \;
>
> Otherwise:
>
> find . -name a -exec sh -c 'ln -s a "${1%a}A"' {} {} \;
>
> --
> Stéphane
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-04-25 19:14   ` Alexy Khrabrov
@ 2007-04-25 21:52     ` Chris Johnson
  2007-04-25 21:58       ` Chris Johnson
  0 siblings, 1 reply; 12+ messages in thread
From: Chris Johnson @ 2007-04-25 21:52 UTC (permalink / raw)
  To: Alexy Khrabrov; +Cc: zsh-users

Alexy Khrabrov sent me the following 2.2K:

> A while ago, Stephane suggested a terrific script on doing things
> right inside find's exec.
> I'm using that magic advice and it works, fantastic!  Still it's a bit
> of a mystery to me.  Why do we need {} {} twice -- although there's
> only one parameter reference to $1?
> 
> Also, how would I generalize it for two commands inside the script?
> Here's an example.  I want to convert a bunch of .tif files to .jpg's.
> The original tifs reside in certain directory structure which should
> be preserved in the target directory.

[...]

> The command to do a single conversion is
> 
> convert -quality 100 dir1/A.tif /jpgs/dir1/A.jpg

I think it'd be simpler to do something like:

   $ cp -r dir1 /jpgs
   $ mogrify -format jpg /jpgs/**/*.tif

Mogrify is also part of the ImageMagick suite, but does the conversion
in place.

This doesn't help you with your general find question, however.

-- 
Chris Johnson
cjohnson@cs.utk.edu
http://www.cs.utk.edu/~cjohnson


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-04-25 21:52     ` Chris Johnson
@ 2007-04-25 21:58       ` Chris Johnson
  2007-04-25 22:26         ` Alexy Khrabrov
  0 siblings, 1 reply; 12+ messages in thread
From: Chris Johnson @ 2007-04-25 21:58 UTC (permalink / raw)
  To: Alexy Khrabrov; +Cc: zsh-users

Chris Johnson sent me the following 1.0K:

> Alexy Khrabrov sent me the following 2.2K:
>
> > The command to do a single conversion is
> > 
> > convert -quality 100 dir1/A.tif /jpgs/dir1/A.jpg
> 
> I think it'd be simpler to do something like:
> 
>    $ cp -r dir1 /jpgs
>    $ mogrify -format jpg /jpgs/**/*.tif

Sorry.  The conversion isn't done in place.  You'll end up with *.tifs
and *.jpgs in the same directory under /jpgs.  You'll want to issue

   $ rm /jpgs/**/*.tif

to get rid of the copies of the originals, or operate in the original
hierarchy and do a selective copy.

-- 
Chris Johnson
cjohnson@cs.utk.edu
http://www.cs.utk.edu/~cjohnson


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-04-25 21:58       ` Chris Johnson
@ 2007-04-25 22:26         ` Alexy Khrabrov
  2007-04-25 22:38           ` Matt Wozniski
  0 siblings, 1 reply; 12+ messages in thread
From: Alexy Khrabrov @ 2007-04-25 22:26 UTC (permalink / raw)
  To: Chris Johnson; +Cc: zsh-users

The cp -r is exactly what I want to avoid with convert, since each
TIFF is a slide scan about 120 MB in size.

BTW, how'd I copy just the directory structure from /tifs/ to /jpgs/
-- directories only -- in the shortest and prettiest way?  :)

(All the questions you always wanted to find out and where afraid to ask!:)

Cheers,
Alexy

On 4/25/07, Chris Johnson <cjohnson@cs.utk.edu> wrote:
> Chris Johnson sent me the following 1.0K:
>
> > Alexy Khrabrov sent me the following 2.2K:
> >
> > > The command to do a single conversion is
> > >
> > > convert -quality 100 dir1/A.tif /jpgs/dir1/A.jpg
> >
> > I think it'd be simpler to do something like:
> >
> >    $ cp -r dir1 /jpgs
> >    $ mogrify -format jpg /jpgs/**/*.tif
>
> Sorry.  The conversion isn't done in place.  You'll end up with *.tifs
> and *.jpgs in the same directory under /jpgs.  You'll want to issue
>
>    $ rm /jpgs/**/*.tif
>
> to get rid of the copies of the originals, or operate in the original
> hierarchy and do a selective copy.
>
> --
> Chris Johnson
> cjohnson@cs.utk.edu
> http://www.cs.utk.edu/~cjohnson
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-04-25 22:26         ` Alexy Khrabrov
@ 2007-04-25 22:38           ` Matt Wozniski
  2007-04-25 23:19             ` Alexy Khrabrov
  0 siblings, 1 reply; 12+ messages in thread
From: Matt Wozniski @ 2007-04-25 22:38 UTC (permalink / raw)
  To: zsh-users

> BTW, how'd I copy just the directory structure from /tifs/ to /jpgs/
> -- directories only -- in the shortest and prettiest way?  :)

If I'm understanding your question correctly, you want to create a
copy of ./tifs called ./jpgs, and have the copy only contain
directories, no files.  Is that correct?

If so, the following should tackle it:

for dir in tifs/**/*(/)
mkdir -p ${dir/tifs/jpgs}

I'm sure that there's a better way to do this that only requires an
"mkdir -p" on each leaf directory, but I can't think of it at the
moment and this should do what you want, if a bit inefficiently.

~Matt


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-04-25 22:38           ` Matt Wozniski
@ 2007-04-25 23:19             ` Alexy Khrabrov
  2007-09-11  7:52               ` Alexy Khrabrov
  0 siblings, 1 reply; 12+ messages in thread
From: Alexy Khrabrov @ 2007-04-25 23:19 UTC (permalink / raw)
  To: Matt Wozniski; +Cc: zsh-users

On 4/25/07, Matt Wozniski <godlygeek@gmail.com> wrote:
> If I'm understanding your question correctly, you want to create a
> copy of ./tifs called ./jpgs, and have the copy only contain
> directories, no files.  Is that correct?

Yes.

> If so, the following should tackle it:
>
> for dir in tifs/**/*(/)
> mkdir -p ${dir/tifs/jpgs}
>
> I'm sure that there's a better way to do this that only requires an
> "mkdir -p" on each leaf directory, but I can't think of it at the
> moment and this should do what you want, if a bit inefficiently.

Cool, and nice use of zsh features already!  This is an artistic
question -- I've been doing different things to mirror a directory
structure only (without files yet), and zsh seems to have some power
features which make it simpler.

Cheers,
Alexy


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-04-25 23:19             ` Alexy Khrabrov
@ 2007-09-11  7:52               ` Alexy Khrabrov
  2007-09-13 23:29                 ` Stephane Chazelas
  2007-09-14  9:10                 ` Atom Smasher
  0 siblings, 2 replies; 12+ messages in thread
From: Alexy Khrabrov @ 2007-09-11  7:52 UTC (permalink / raw)
  To: zsh-users

A while ago I asked about generalization of the nested command in find
-exec.  What if I have to execute a random series of shell commands
for each file found by find and given to exec -- how should I package
the series under zsh?  I tried -exec (cmd1; cmd2; cmd3) and it seems
not to work -- find complains about ( and ) and loses ; ...  Is it a
shell-sensitive problem or find-specific?

Cheers,
Alexy


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-09-11  7:52               ` Alexy Khrabrov
@ 2007-09-13 23:29                 ` Stephane Chazelas
  2007-09-14  9:10                 ` Atom Smasher
  1 sibling, 0 replies; 12+ messages in thread
From: Stephane Chazelas @ 2007-09-13 23:29 UTC (permalink / raw)
  To: Alexy Khrabrov; +Cc: zsh-users

On Tue, Sep 11, 2007 at 09:52:19AM +0200, Alexy Khrabrov wrote:
> A while ago I asked about generalization of the nested command in find
> -exec.  What if I have to execute a random series of shell commands
> for each file found by find and given to exec -- how should I package
> the series under zsh?  I tried -exec (cmd1; cmd2; cmd3) and it seems
> not to work -- find complains about ( and ) and loses ; ...  Is it a
> shell-sensitive problem or find-specific?
[...]

Like any other shell. Here, it's down to find syntax, not zsh
syntax.

So

find ... -exec cmd1 \; -exec cmd2 \; -exec cmd3 \;

But beware cmd2 will only be executed if cmd1 succeeds (returns
a non-null return code).

Or;

find ... -exec sh -c '
   cmd1
   cmd2
   cmd3' \;

That's an inline script. If you want to pass arguments to that
script beware that the first one will be available as $0, not
$1. It's not true for very old or non standard shell, that's why
you sometimes find:

find ... -exec sh -c '
  cmd1 -- "$1"
  cmd2 -- "$1"' {} {} \;

Or if you want to user the + syntax to pass more than one file
path at the same time:

find ... -exec sh -c '
  shift "$1"
  for file
  do cmd -- "$file"
  done' 2 1 {} +

But with modern shs, you should be able to do:

find ... -exec sh -c '
  cmd1 -- "$0"
  cmd2 -- "$0"' {} \;

find ... -exec sh -c '
  for file
  do cmd -- "$file"
  done' inline {} +

But with zsh, you generally no longer need find as zsh's
globbing can do almost everything find can do.

-- 
Stéphane


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-09-11  7:52               ` Alexy Khrabrov
  2007-09-13 23:29                 ` Stephane Chazelas
@ 2007-09-14  9:10                 ` Atom Smasher
  2007-09-14 15:41                   ` Bart Schaefer
  1 sibling, 1 reply; 12+ messages in thread
From: Atom Smasher @ 2007-09-14  9:10 UTC (permalink / raw)
  To: zsh-users

On Tue, 11 Sep 2007, Alexy Khrabrov wrote:

> A while ago I asked about generalization of the nested command in find 
> -exec.  What if I have to execute a random series of shell commands for 
> each file found by find and given to exec -- how should I package the 
> series under zsh?  I tried -exec (cmd1; cmd2; cmd3) and it seems not to 
> work -- find complains about ( and ) and loses ; ...  Is it a 
> shell-sensitive problem or find-specific?
================

i'm sure there's other ways to do this, but i do something like this...

find /path -param | while read n
do
 	cmd1 $n ; cmd2 $n
 	cmd3 $n
done

as long as there aren't white spaces in the output of find, everything 
stays simple. off the top of my head, i think that white spaces can be 
handled by double-quoting references to $n.


-- 
         ...atom

  ________________________
  http://atom.smasher.org/
  762A 3B98 A3C3 96C9 C6B7 582A B88D 52E4 D9F5 7808
  -------------------------------------------------

 	"I tried marijuana once. I did not inhale."
 		-- William J. Clinton, 30 Mar 1992

 	"I did not have sexual relations with that
 	 woman, Miss Lewinsky."
 		-- William J. Clinton, 26 Jan 1998



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: script within find
  2007-09-14  9:10                 ` Atom Smasher
@ 2007-09-14 15:41                   ` Bart Schaefer
  0 siblings, 0 replies; 12+ messages in thread
From: Bart Schaefer @ 2007-09-14 15:41 UTC (permalink / raw)
  To: zsh-users

On Sep 14,  9:10pm, Atom Smasher wrote:
}
} find /path -param | while read n
} do
}  	cmd1 $n ; cmd2 $n
}  	cmd3 $n
} done
} 
} as long as there aren't white spaces in the output of find, everything 
} stays simple.

Trailing whitespace (a series of IFS characters) is stripped by read,
and backslashes have special meaning.

To avoid this you can do

    find /path -param -print0 | while IFS= read -rd $'\0' n



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2007-09-14 15:43 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-24  7:39 script within find Alexy Khrabrov
2007-02-24 10:08 ` Stephane Chazelas
2007-04-25 19:14   ` Alexy Khrabrov
2007-04-25 21:52     ` Chris Johnson
2007-04-25 21:58       ` Chris Johnson
2007-04-25 22:26         ` Alexy Khrabrov
2007-04-25 22:38           ` Matt Wozniski
2007-04-25 23:19             ` Alexy Khrabrov
2007-09-11  7:52               ` Alexy Khrabrov
2007-09-13 23:29                 ` Stephane Chazelas
2007-09-14  9:10                 ` Atom Smasher
2007-09-14 15:41                   ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).