I've only been doing scripting a few weeks, and I've managed to write the script at the bottom of this post and get it to work. However, I know that what I need to do really is move the bottom if statement condition into the if statement above. So I need to do a condition like this:
If file exists (and isn't a empty string) AND is either one of these 2: ("switchport mode access" OR "switchport trunk allowed vlan").
I feel that if I did something like the below (not sure the syntax is correct, but doesn't matter because I'm just explaining):
###### 1 ##### ################ 2 #################### ######## 3 ########
if ([ ! -z "${prev}" ] && [ "$line" = "switchport access vlan $i" ] || [[ $line =~ $regex ]]);then
Then I'm worried I don't understand how it groups it. So if we call each condition 1,2,3. So does it mean condition 1&2 OR 3. Or does this man condition 1 & (2-OR-3)? Like, is there a way I could even clear up any ambiguity like you would in maths by putting brackets around the bits you want to group. What's the right way to do it?
tmpfiles="$PWD/configs/*.tmp"
prev=
for basefile in $tmpfiles
do
while read line
do
## get old vlans and interfaces
for i in "${oldvlans[@]}"
do
if ([ ! -z "${prev}" ] && [ "$line" = "switchport access vlan $i" ]);then
line1="${prev}"
line2="${line}"
echo "${line1}"
echo "${line2}"
fi
done
### check for lines with "trunk allowed vlans" on and do a no trunk allowed vlan on them
regex="switchport trunk allowed vlan*"
if [ ! -z "${prev}" ] && [[ $line =~ $regex ]];then
line1="${prev}"
line2="${line}"
echo "${line1}"
echo "no ${line2}"
fi
prev="${line}"
done < "$basefile" > "$basefile.done"
EDIT: I did some testing below to try and work out the logic since stephane said () is not for grouping test conditions, and I'm confident I proved him/her wrong):
$ var1=sumit ; [ -z "var1" ] && ([ "$var1" = "sxxt" ] || [ "$var1" = "sumit" ]); echo $?
1
$ var1=sumit ; [ -n "var1" ] && ([ "$var1" = "sxxt" ] || [ "$var1" = "sumit" ]); echo $?
0
So I think this is the correct way to do a test where I want:
If [condition1] AND if ([condition 2] OR [condition 3] are true).
But I'm just hacking away at it, and need to just try and get it clarified.
(...)
is to run subshells insh
, it's not for grouping nor to wrap the condition part of an if statement. For grouping commands, there's{ ...; }
, but you don't need it there. – Stéphane Chazelas Dec 23 '22 at 09:27#!/bin/bash
)? – terdon Dec 23 '22 at 09:37[[ ]]
conditional expressions, which allow parentheses and&&
and||
inside them, making this sort of thing much easier.[ ]
test expressions have much more limited and confusing syntax, and you shouldn't try this inside them. – Gordon Davisson Dec 23 '22 at 10:38(..)
are used to run commands in subshells not for simple grouping. – terdon Dec 23 '22 at 10:49switchport trunk allowed vlan*
would match a stringswitchport trunk allowed vla
, and then zero or more lettersn
. That's different from the shell pattern syntax where*
means any number of any characters. – ilkkachu Dec 23 '22 at 11:57[ -z "var1" ]
there would check to see ifvar1
is an empty string. It isn't, so that test will always be falsy, which makes the whole condition meaningless. – ilkkachu Dec 23 '22 at 14:29