fyd
fyd

Reputation: 11

csh: set: No match

I define a function, an array and a variable:

set fnctn = "F(x)=Vx1*(1+cos(1*x-pi))"  
set Vx = ( 1 1 1 1 )  
set Vx1 = $Vx[1]  

The following commands do what I want:

echo "$fnctn" | sed "s/Vx1/$Vx1/"  
set fnctn2 = `echo "$fnctn" | sed "s/Vx1/$Vx1/"`   
echo "$fnctn2"  

or even:

echo "$fnctn" | sed "s/Vx1/$Vx[1]/"  

But storing the answer to the later command in a variable such as:

set fnctn2 = `echo "$fnctn" | sed "s/Vx1/$Vx[1]/"` 

reports the following error message:

set: No match.  

Where is the trick?

ps: please do not suggest me to switch to bash :-) -

Upvotes: 1

Views: 3676

Answers (2)

ivan_pozdeev
ivan_pozdeev

Reputation: 36028

The catch here is that for $Vx[1], filename substitution is for some reason attempted twice: apparently, first on evaluation of the variable, then on the evaluation of the result of the command substitution. While for $Vx1, it's only attempted once, on variable substitution:

> ls
f1 f2 f3
> echo *
f1 f2 f3
> set v=("*" "?2")
> set v1="$v[1]"
> set echo=1

> echo `echo ${v1}`
echo `echo ${v1}`
echo *
f1 f2 f3
> echo `echo "${v1}"`
echo `echo "${v1}"`
echo *
*
> echo "${v[1]}"
echo *
*
> echo `echo "${v[1]}"`
echo `echo "${v[1]}"`
echo *
f1 f2 f3

My guess about the reason is because array indices are also subject of variable substitution, $Vx[1] is marked "substitute twice" or something, and the resulting "*" has "one substitution left yet". The man page doesn't say anything relevant, so if it's by design, the link is too subtle for me. Though it is definitely a side effect of the existing implementation, whatever it is. This is a bug in my book -- at least, the fact that this behavior is not documented.


The way around that I've found is to quote the command substitution clause. Now, escaping the quotes inside with a backslash doesn't work reliably and is prone to giving parsing errors depending on the expression inside. The way that worked for me in this case was to use single quotes inside:

> echo "`echo '$fnctn' | sed 's/Vx1/$Vx[1]/'`"
echo `echo 'F(x)=Vx1*(1+cos(1*x-pi))' | sed 's/Vx1/1/'`
sed s/Vx1/1/
echo F(x)=Vx1*(1+cos(1*x-pi))
F(x)=1*(1+cos(1*x-pi))

This is just one of the examples of csh's poor/unpolished design that causes people to recommend against using it.

Upvotes: 0

Beta
Beta

Reputation: 99094

Because of the square brackets, csh interprets the word as a pattern and tries to do filename substitution ("globbing") on it. Since you don't have any files with names that match that "pattern", it tells you that it can't find a match.

Just inhibit filename substitution like this:

set noglob

before you attempt the assignment.

Upvotes: 1

Related Questions