3

Here is output of:

sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null 
Yash Shah
CoreFragment
CoreFragment_5G
CoreFragment
dlink
Yash Shah
COMFAST
Appbirds_Technologies
SYMBIOSIS
20096641
CoreFragment_5G
AMBER_AP1
REDWING LABS_5G

While the same thing written in a script is not working the same.

Here is a snippet in which I used above command.

for ssid_name in $(sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null)
do
    echo "$ssid_name"
done

I got output like this:

Yash
Shah
CoreFragment
CoreFragment_5G
CoreFragment
Yash
Shah
REDWING
LABS
COMFAST
Appbirds_Technologies
SYMBIOSIS
CoreFragment_5G
REDWING
LABS_5G

Note: When there is a space in output it take as a new line.

I'm working on Ubuntu 18.04.

  • Not a duplicate, but the whitespace problem is discussed here: unix.stackexchange.com/q/9496/173368 – Haxiel Jan 16 at 8:20
  • i didn't find that (might be due to word match) so I created question – Yash Shah Jan 16 at 8:23
  • No problem. I wanted to link to that QA because it contains several comprehensive answers that go into the details of that problem. – Haxiel Jan 16 at 8:25
  • yaa... it's really useful link – Yash Shah Jan 16 at 8:40
8

First, note that it is not one command behaving differently. In your code snippets, standard output is written by two quite different commands.
Your first one prints sed's output, while in your second one:

  1. The output of sed is substituted (by the command substitution $(...)) after in;
  2. The resulting string is expanded into a list of elements;
  3. Each item is in turn assigned to ssid_name and printed by echo.

Expansion in point 2 is performed according to the value of the internal field separator (IFS), which by default is <space><tab><newline>. Thus, your solution works because it lets for split the substituted string on newlines only.

As an aside on your answer, note that $'\n' is not portable - even if that syntax ($'string') is supported in many shells.
You can nevertheless use an assignment like this:

IFS='
'

An alternative construct for processing lines of input is using read in a while loop:

sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null |
while IFS= read -r i; do
    printf '%s\n' "$i"
done

Here, too, each line of sed's output is split according to the value of IFS - that in this example is set to the null string exactly to prevent any effects of word splitting - but lines would be kept separated by read regardless of IFS.

3

Better use a while loop with read instead of a for loop.

sudo iwlist scan 2>/dev/null |grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null | while IFS= read -r ssid_name
do
    echo $ssid_name
done

see also https://mywiki.wooledge.org/BashFAQ/001

1

By adding following line in code before for loop, work perfactly in my case.

IFS=$'\n'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.