Path: utzoo!attcan!uunet!island!daniel From: daniel@island.uu.net (Dan "1461 days of Bush is 1462 too many..." Smith) Newsgroups: comp.unix.wizards Subject: Re: Shell script help needed Keywords: Suspend a foreach() loop? Message-ID: <493@island.uu.net> Date: 23 Nov 88 17:27:21 GMT References: <1872@loral.UUCP> Reply-To: daniel@island.uu.net (Dan Smith) Organization: Island Graphics, Marin County, California Lines: 90 In article <1872@loral.UUCP> jlh@loral.UUCP (Physically Pffft) writes: >Our application has it's source code in 9 directories, and I find that >often I need to make similar changes in all 9 directories. Manually >cd'ing into each directory is error prone, some are skipped and others >are entered more than once. I'd like to write a shell script to automate I deal with this every single day! :-) Here's my strategy/tutorial: use foreach to pushd all of the directories in a tree [optionally set up a label] do whatever needs to be done the directory pop the directory [optionally goto the label] so from csh you could have: (skip RCS directories) % foreach i (`find -name RCS -prune -o -type d -print`) ? pushd $i ? end to push all all of the directories in a tree...be careful with $cdpath, or you may not get what you want... How I usually do it... I have an alias called "fed" (foreach directory) that sources a script via: alias fed 'source ~$misc_bin_person/bin/ptree' and here is "ptree" (pushd tree) ---- # note, this must be sourced... set savecdpath=($cdpath) set cdpath=( . .. ../.. ../../.. ../../../../..) echo -n looking at directories... foreach i (`find -name RCS -prune -o -type d -print`) p $i end set cdpath=($savecdpath) unset savecdpath ---- ...and here are my relevant cd/pushd/popd aliases: ----- # # aliases for setting the prompt and getting around # # fillstr is a var used in prompt, contains "(level)" when dirs are pushed set fillstr="" set end=":-)" alias prompt_set 'set prompt_head=$cwd:h;set prompt="\! $HOST"":$prompt_head:t/$cwd:t$fillstr $end "' alias cd 'set old=$cwd; chdir \!*; prompt_set; if -e .locrc source .locrc' alias dir_number 'set fillstr; set dnum=`dirs`; shift dnum; if ($#dnum >= 1) set fillstr=" ($#dnum)"' alias p 'set o2=$cwd; pushd \!* > /dev/null; set pdirs=`dirs`; echo $pdirs:gt; set old=$o2; dir_number; prompt_set' alias pp 'set o2=$cwd; popd; set old=$o2; dir_number; prompt_set' alias fed 'source ~$misc_bin_person/bin/ptree' ----- Now...getting back to handling a tree, I go up to the root directory of a product and type "fed". All of the directories get pushed, and the prompt indicates how many levels down I am. If I'm going to do something fairly repetitive, I may set up a label via: % foo: and then do whatever I need... then to pop directories I enter "pp", and my prompt changes to reflect where I am and how many directories deep... If I had set a label, I could say something like "goto foo" (note, no colon), and things will pretty much run themselves until all of the directories are popped. I take advantage of the fact that it is an error to not have a directory to pop to; that ends the loop. Hope this helps you and others that work with projects that have many directories/levels. dan -- DanSmith IslandGraphics 4000CivicCenterDr SanRafael MarinCo CA 94903 4154911000 415 332 FAST(h) 491 0402(Fax)|d: Nobodys' fault but mine| UnixFeastsMusicFilm daniel@island.uu.net unicom!daniel@pacbell.com {lll-crg,apple}!well!dansmith