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.

4
  • Not a duplicate, but the whitespace problem is discussed here: unix.stackexchange.com/q/9496/173368
    – Haxiel
    CommentedJan 16, 2019 at 8:20
  • i didn't find that (might be due to word match) so I created question
    – Yash Shah
    CommentedJan 16, 2019 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
    CommentedJan 16, 2019 at 8:25
  • yaa... it's really useful link
    – Yash Shah
    CommentedJan 16, 2019 at 8:40

3 Answers 3

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'

        You must log in to answer this question.

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.