Comando não funciona corretamente no shell script

Comando não funciona corretamente no shell script

Aqui está a saída de:

sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null 
Yash Shah
CoreFragment
CoreFragment_5G
CoreFragment
link
Yash Shah
CONFORTÁVEL
Appbirds_Tecnologias
SIMBIOSE
20096641
CoreFragment_5G
AMBER_AP1
LABORATÓRIOS REDWING_5G

Embora a mesma coisa escrita em um script não funcione da mesma forma.

Aqui está um trecho no qual usei o comando acima.

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

Eu obtive uma saída assim:

Yash
CoreFragment
CoreFragment_5G
CoreFragment
Yash
ASA VERMELHA
LABORATÓRIOS
CONFORTÁVEL
Appbirds_Tecnologias
SIMBIOSE
CoreFragment_5G
ASA VERMELHA
LABS_5G

Observação: Quando há um espaço na saída, ele é considerado uma nova linha.

Estou trabalhando no Ubuntu 18.04.

Responder1

Primeiro, observe que não éumcomando se comportando de maneira diferente. Nos seus trechos de código, a saída padrão é escrita por dois comandos bastante diferentes.
Seu primeiro imprime seda saída de, enquanto no segundo:

  1. A saída de sedé substituída (pelo comando replacement $(...)) depois de in;
  2. A string resultante é expandida em uma lista de elementos;
  3. Cada item é, por sua vez, atribuído ssid_namee impresso por echo.

A expansão no ponto 2 é realizada de acordo com o valor do separador de campo interno ( IFS), que por padrão é <space><tab><newline>. Por isso,sua soluçãofunciona porque permite fordividir a string substituída apenas em novas linhas.

Além da sua resposta, observe que $'\n'não é portátil - mesmo que essa sintaxe ( $'string') seja suportada em muitos shells.
No entanto, você pode usar uma tarefa como esta:

IFS='
'

Uma construção alternativa para processar linhas de entrada é usar readem whileloop:

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

Aqui, também, cada linha da sedsaída de é dividida de acordo com o valor de IFS- que neste exemplo é definido como a string nula exatamente para evitar quaisquer efeitos de divisão de palavras - mas as linhas seriam mantidas separadas por readindependentemente de IFS.

Responder2

Melhor usar um whileloop com readem vez de um forloop.

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

Veja tambémhttps://mywiki.wooledge.org/BashFAQ/001

Responder3

Adicionando a seguinte linha no código antes do loop for, funciona perfeitamente no meu caso.

SE=$'\n'

informação relacionada