0

I've had a good read of How do you tell if a string contains another string in Unix shell scripting? but I am struggling to get my code working with this as an example.

I am doing this in the default FreeBSD shell /bin/sh. No bash answers please.

Here is my code

while
        : ${start=$i}
        var1="$(command | awk -v awk_i=$i  'NR==awk_i { print $1 }')" 
                if test ${var1#*$var2} = $var2
                then
                        row=$i
                        break
                fi
        i="$(( $i+1 ))"
        [ "$i" -lt $iterate ]
do :;
done

I know that var1 is working OK because the test fails and continues to iterate through the series until the end. The problem is that when the test should pass, the variable for var1 is empty.

Here's some debug output where we have the iteration happening, the correct value for var2 being found and the test in theory passing, and then because the variable isn't expressed as part of the test properly, it keeps going.

+ awk -v 'awk_i=27' 'NR==awk_i { print $1 }'
+ var1=file/path/variable
+ test file/path/variable '=' var2
+ i=28
+ [ 28 -lt 52 ]
+ :
+ : 2
+ command
+ awk -v 'awk_i=28' 'NR==awk_i { print $1 }'
+ var1=file/path/variable
+ test '=' var2
test: =: unexpected operator
+ i=29
+ [ 29 -lt 52 ]
+ :
+ : 2
+ command
+ awk -v 'awk_i=29' 'NR==awk_i { print $1 }'
+ var1=file/path/variable
+ test file/path/variable '=' var2
+ i=30
+ [ 30 -lt 52 ]

I've even tried this alternate method: ##*/ use in UNIX Shell Scripting

if ${var1##*/$var2} = $var2

Can anyone make any suggestions why the variable is ending up blank and thus the test fails for the correct entry? Is it the / that could be causing havoc? (Though the other outputs are fine it seems)

Thanks

  • what exactly do you want to do, what is your input? also in FreeBSD, you have [csh](https://www.freebsd.org/cgi/man.cgi?csh(1)) by default just in case. – nbari Aug 26 '17 at 19:25
  • @nbari I'm looking to iterate through zfs datasets looking for various different things. It seems to be failing when it finds the dataset that the getopts is looking for to be very specific. – Madtempest Aug 26 '17 at 23:54
  • `dataset_name="$(zfs list | awk -v awk_i=$i 'NR==awk_i { print $1 }')" if ${dataset_name#*$dataset} = $dataset then row=$i break` Does that help? – Madtempest Aug 27 '17 at 00:04

1 Answers1

0

Probably something like this may help:

#!/bin/sh

zfs list | while read -r line; do
        var1=$(echo $line | awk '{print $1'})
        echo ${var1}
        # your logic here
        # ...
done

In this base script, instead of calling multiple times the command zfs list (on each interaction) is just used once and the output latter is used to form/create variables and custom conditions.

nbari
  • 25,603
  • 10
  • 76
  • 131
  • Thanks. I'll give it a go and see let you know how it goes! – Madtempest Aug 27 '17 at 08:25
  • `zfs list | while read -r line; do dataset_name=$(echo $line | awk '{print $1'}) if ${dataset_name#*$dataset} = $dataset then echo ${dataset_name} break fi done` Unforunately this still fails for the exact same reason. It's as though I need to set $dataset to " " or something for it to work. – Madtempest Aug 27 '17 at 08:33
  • what's wrong with defining dataset=0 ? second, you just want to check if dataset_name ends with X bar? for example, `zroot/var/tmp` check if ends with `tmp` ? – nbari Aug 27 '17 at 08:43
  • Yes and I want that entire line for later use as well so I can extract other data from it. – Madtempest Aug 27 '17 at 09:30
  • Results of what I pasted above: `+ read -r line + echo zroot/var XG XG XG /zroot/var/tmp + awk '{print $1}' + dataset_name=zroot/var + zroot/var '=' tmp test: zroot/var: not found + read -r line + echo zroot/var/tmp XG XG XG zroot/var/tmp + awk '{print $1}' + dataset_name=zroot/var/tmp + '=' tmp test: =: not found` – Madtempest Aug 27 '17 at 09:36
  • Final working code: `dataset_name=$(echo $line | awk '{print $1}') if test "${dataset_name##*$dataset}" = "" then` Thanks for the guiding hand – Madtempest Aug 29 '17 at 12:24