0

I am modifying a suite of scripts written in tcsh. Unfortunately, these scripts can't be rewritten because the program they interface with is also written in tcsh. I just want to get out of the way the idea that if I could rewrite these in BASH or literally any other language, I would.

As part of these scripts many of our variables are saved in arrays. My question is: Is there a way in tcsh where you can query if the content of a variable is present in an array (regardless of its position in the array) without using loops?

For example, I have the following array of valid ROI names:

set shortROI = {"lAmy_","mAmy_","A32p_","A32sg_"}

When the user executes the script they have an option to use a flag to say they want to redo processing for one or more specific ROIs from the options above. So like, if the flag is -remake_ROI, as part of calling the script they could add -remake_ROI lAmy or -remake_ROI lAmy A32p_ to remake those ROIs only. I have a very large while loop currently processing all possible flags but the section relevant here looks like this:

set ac = 1
set redo_rois  = 0
set roi_proc_list = 

        while ( $ac <= $#argv )
        foreach roi_opt ( $shortROI )
            if ( "$argv[$ac]" == $roi_opt )
                @ redo_rois ++
                set roi_proc_list = ( $roi_proc_list $roi_opts )
            endif
        end
        @ ac ++
    end

ac is the command line argument count, redo_rois is the number of ROIs to re-process and roi_proc_list is the actual list to redo. I was wondering instead of the many loops, if there was something like if ( "$argv[$ac]" == "$shortROI[*]" ) that would get the job done.

Thank anyone for their help.

1 Answer 1

1
if ( " $shortROI " =~ *" $argv[$ac] "* ) then
   ...
endif

Example:

set list = (foo bar baz)

foreach a ($*)
        if(" $list " =~ *" $a "*) then
                echo "$a in list"
        else
                echo "$a NOT in list"
        endif
end

This may incorrectly return true if either the variable on the right side or any of the words from the list contain spaces. If you can decide on a character which cannot appear in either side (eg. @), you can replace the spaces with it in each word:

foreach a ($*:q)
        if(" $list:q:gas/ /@/ " =~ *" $a:q:as/ /@/ "*) then
        ...
2
  • Thank you for this - it's just what I was looking for. I appreciate the caveats about the spaces as well. Commented Aug 27, 2019 at 21:22
  • Great idea for how to handle spaces! Using octal, you can substitute with a non-printable character instead of '@'. I successfully used " $list:q:gas/ /\0177/ ", for example. Commented Mar 24, 2021 at 2:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .