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 ifvar1is 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