Brenton
Brenton

Reputation: 35

In ash how to set multiple line output to variables

Edit #3: My question has been closed and marked as duplicate which I am unable to follow. I posted here because I was asking for help :(

enter image description here

I'm familiar with doing this type of thing in batch but can't work out how to do it in ash (edit: ash not bash). I'm searching an openwrt configuration file /etc/config/wireless for wifi-iface settings.

So far I can get the required output:

root@OpenWrt:~# awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g
default_radio0
default_radio1
wifinet1

My question is how can I turn this output into variables like using a for f loop?

Edit #1: Something like:

root@OpenWrt:~# echo $a
default_radio0

root@OpenWrt:~# echo $b
default_radio1

root@OpenWrt:~# echo $c
wifinet1

Edit #2: I'm guessing i need to change the output from lines to string:

root@OpenWrt:~# awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g
 | xargs
default_radio0 default_radio1 wifinet1

Getting closer but then how does the for loop work?

Upvotes: 0

Views: 1709

Answers (3)

Brenton
Brenton

Reputation: 35

Thanks for your help @dash-o and @KamilCuk I finally managed to figure out what to do:

#!/bin/sh

function list_wifi {
wifi=$(awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g)

count=0 && for string in $wifi
  do
    eval ap$((++count))=$string
  done

ap=$(echo "$wifi" | wc -l)
  if [[ $ap -eq 1 ]];
    then
      echo next_function
    else
      echo "--Multiple APs detected"
  fi

count=0 && for string in $wifi
  do
    echo $((++count))-$string
  done

x=0 && while [[ $x -lt 1 || $x -gt $ap ]]
  do
    printf "--Select AP to clone (1-$ap): "
    read x
  done
}

Results in:

root@OpenWrt:~# sh test
--Multiple APs detected
1-default_radio0
2-default_radio1
3-wifinet1
--Select AP to clone (1-3):

With variables:

echo $ap1
default_radio0
echo $ap2
default_radio1
echo $ap3
wifinet1

Upvotes: 0

KamilCuk
KamilCuk

Reputation: 141613

turn this output into variables like using a for f loop?

Then the first snippet from the other answer is enough.

how to set multiple line output to variables

In general, save the whole output somewhere. From there, extract lines, one at a time, and assign to variables, if you wish. A more shell-ish way would to parse the data in a pipeline as they go without storing it anywhere.

I am trying to set three variables $a $b $c

A good POSIX way with a temporary file and a read:

tmpf=$(mktemp)
awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g > "$tmpf"
{
   # read three lines of input
    IFS= read -r a
    IFS= read -r b
    IFS= read -r c
} < "$tmpf"
rm "$tmpf"

But without a temporary file, you can invoke three processes to extract the lines:

tmp=$(awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g)
a=$(printf "%s\n" "$tmp" | sed '1!d')
b=$(printf "%s\n" "$tmp" | sed '2!d')
c=$(printf "%s\n" "$tmp" | sed '3!d')

or maybe a bit clearer with tab separated content:

tmp=$(awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g | paste -s)
a=$(printf "%s\n" "$tmp" | cut -f1)
b=$(printf "%s\n" "$tmp" | cut -f2)
c=$(printf "%s\n" "$tmp" | cut -f3)

I'm guessing i need to change the output from lines to string:

Lines are strings.

is there a way to read all lines 1 to x?

Just don't remove lines from specific range.

x=50; 
... | sed "1,$x!d"

Upvotes: 1

dash-o
dash-o

Reputation: 14493

You can capture the output of a command into a variable using the $(command) construct:

wireless_list=$(awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g)
for w in ${wireless_list} ; do
    # Do something with $w
    echo "$w"
done

Alternative approach, using array (which will be safer to evaluate):

readarray -t wireless_list <<< "$(awk '/wifi-iface/ {print $3}' /etc/config/wireless | sed s/\'//g)"
for w in "${wireless_list[@]}" ; do
    # Do something with $w
    echo "$w"
done

Upvotes: 0

Related Questions