My file structure is like this.

unix% ls
NGC2201 IC0499 IC7216 NGC7169
unix% cd NGC2201
unix% ls
7019 2221 note

where 7019 and 2221 are new directories and note is a text file that I use to create variables. The contents within 2221 and 7019 are important, but do not need to be set as variables; my scripts afterwords will take care of all of that.

My current script is the following:

# The purpose of this script is to take the note files provided and set the values as variables.

#!/bin/csh -f

set z=`grep -E '^z=' note | cut -d= -f2`
set nh=`grep 'NH' note | cut -d= -f2`
set xc=`grep 'Center' note | cut -d, -f1 | cut '-d' -f4`

echo $z $nh $xc

This sets three variables for use in the current directory (in this case, we will use NGC2201 as the parent directory and 7019 and 2221 as the sub-directories for these variables to be used on).

My question is how do I write a script to automatically set NGC2201 as a variable named $g and 2221 as a variable named $obs.

After the script runs through 2221, I would like it to then set the directory as 7019 and repeat the steps. After the directories within NGC2201 are finished, I would like the script to move on to IC0499, repeat the process, etc.

How do I get the script to run through the directories? I cannot make it global because it cannot be too intrusive; I need it to only go two directories deep to be satisfactory.

I would like to keep it within csh if possible, but if this is easier in tcsh or bash, I am all for it. Additionally, if there is an easier solution than looping it like this, I am all for that too.


In csh, you can use a foreach loop to loop over every subdirectory of the directories in the current directory:

foreach i (*/*/)
  set g=`echo $i | cut -d/ -f1`   # slash-delimited, select first field
  set obs=`echo $i | cut -d/ -f2` # slash-delimited, select second field
  echo $g $obs

The bash equivalent is a for loop. Of course you can use cut as above, but bash also has an elaborated Parameter Expansion feature, so you don’t need to call anything external:

for i in */*/; do
  g=${i%%/*}   # cut everything from the first slash 
  obs=${i#*/}  # cut everything until first slash
  obs=${obs%/} # cut slash at the end
  echo $g $obs

Substitute the echo line with whatever you want to do with the variables.

Example run

% is the csh prompt, $ the bash one.

% tree    
├── IC0499
├── IC7216
│   └── 2222
├── NGC2201
│   ├── 2221
│   ├── 7019
│   └── note
└── NGC7169

7 directories, 1 file

% foreach i (*/*/)
? set g=`echo $i | cut -d/ -f1`
? set obs=`echo $i | cut -d/ -f2`
? echo $g $obs
? end
IC7216 2222
NGC2201 2221
NGC2201 7019

$ for i in */*/; do g=${i%%/*}; obs=${i#*/}; obs=${obs%/}; echo $g $obs; done
IC7216 2222
NGC2201 2221
NGC2201 7019

Citing https://www.cyberciti.biz/faq/csh-shell-scripting-loop-example/:

Please note that csh was popular for many innovative features but csh has never been as popular for scripting. If you are writing system level rc scripts avoid using csh. You may want to use /bin/sh for any scripts that might have to run on other systems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.