0

I'm trying to read a file, with the condition that if my current line has a regex of the below, then print both the current line and previous line. However I do not get any output at all.

$ cat xc
#!/bin/bash
prev=
regex="switchport trunk allowed vlan*"
while read line
do
    if [ -n "${prev}" ] && [[ $line =~ $regex ]];then
        line1="${prev}"
        line2="${line}"
        echo "${line1}"
        echo "${line2}"
    fi
done < as159.tmp

$ ./xc

When testing the condition without the $prev section (i commented it out, as shown below), I can see that I do get output:

$ cat xc
#!/bin/bash
prev=
regex="switchport trunk allowed vlan*"
while read line
do
    #if [ -n  "${prev}" ] && 
    if [[ $line =~ $regex ]];then
        line1="${prev}"
        line2="${line}"
        echo "${line1}"
        echo "${line2}"
    fi
done < as159.tmp


$ ./xc

switchport trunk allowed vlan 40,10,30

switchport trunk allowed vlan 10,20,30,50,100

So it must be a condition problem, which I'm not sure what it is.

john smith
  • 676
  • 4
  • 13
  • 24
  • Always first test your broken script to https://shellcheck.net before asking here. Thanks – Gilles Quénot Dec 19 '22 at 23:01
  • [[ is a bash keyword similar to (but more powerful than) the [ command. See and . Unless you're writing for POSIX sh, we recommend [[. – Gilles Quénot Dec 19 '22 at 23:10
  • Well this correction now doesn't actually work looking at this again. It is not printing out the previous line – john smith Dec 19 '22 at 23:11
  • I'm going to re-write my question, since you had a problem with it – john smith Dec 19 '22 at 23:16
  • 3
    *"However I do not get the previous line's output"*. Your variable `prev` is never assigned with a value. Thus `line1="${prev}"` always will show *nothing* – Edgar Magallon Dec 19 '22 at 23:27
  • 1
    Oh my god, I can't believe I missed that. Excellent! I just added prev="${line}" just above done, and everything works. Thank you, my hero! I've only been practising shell scripting for a week or two, so forgive me :) Should you put this as an answer, and I mark with a tick? – john smith Dec 19 '22 at 23:30
  • 1
    That regex pattern doesn't make much sense. The `*`in `... vlan*` means zero or more of the "n" character (so it'd match "... vla", "... vlan", "... vlannnnn", etc). I suspect you meant it to match any string (which would be `... vlan.*` in regex), but that's not needed or relevant, since the regex doesn't need to match the entire string, it just has to match somewhere in the string. What are you actually trying to search for? – Gordon Davisson Dec 20 '22 at 01:14
  • Also, `"$prev"`, `"$line"`, `"$line1"` and `"$line2"` would be good enough — you don’t need the `{` and `}`.  See [``${variable_name}`` doesn’t mean what you think it does ….](https://unix.stackexchange.com/q/32210/80216#286525) – G-Man Says 'Reinstate Monica' Dec 20 '22 at 11:57

1 Answers1

1

The main problem is about your variable prev since this one has never a value. So the solution is to assign it a value like this:

...
while read line
do
    #if [ -n  "${prev}" ] && 
    if [[ $line =~ $regex ]];then
        line1="${prev}"
        line2="${line}"
        echo "${line1}"
        echo "${line2}"
    fi
prev="$line"
done < as159.tmp
...

Btw, using line1="${prev}" and line2="${line}" is redundant (unless you want to manipulate the values without affecting the original variables). So, you can simply use:

...
while read line
do
    #if [ -n  "${prev}" ] && 
    if [[ $line =~ $regex ]];then
        echo "${prev}"
        echo "${line}"
    fi
prev="$line"
done < as159.tmp
...
Edgar Magallon
  • 4,711
  • 2
  • 12
  • 27