El comando no funciona correctamente en el script de shell

El comando no funciona correctamente en el script de shell

Aquí está el resultado de:

sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null 
yash shah
Fragmento central
CoreFragment_5G
Fragmento central
enlace
yash shah
COMODIDAD
Appbirds_Tecnologías
SIMBIOSIS
20096641
CoreFragment_5G
ÁMBAR_AP1
LABORATORIOS REDWING_5G

Mientras que lo mismo escrito en un guión no funciona igual.

Aquí hay un fragmento en el que utilicé el comando anterior.

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

Obtuve un resultado como este:

yash
Cha
Fragmento central
CoreFragment_5G
Fragmento central
yash
Cha
ALA ROJA
LABORATORIOS
COMODIDAD
Appbirds_Tecnologías
SIMBIOSIS
CoreFragment_5G
ALA ROJA
LABS_5G

Nota: Cuando hay un espacio en la salida, se toma como una nueva línea.

Estoy trabajando en Ubuntu 18.04.

Respuesta1

Primero, tenga en cuenta que no esunocomando comportándose de manera diferente. En sus fragmentos de código, la salida estándar se escribe mediante dos comandos bastante diferentes.
El primero imprime sedla salida, mientras que el segundo:

  1. La salida de sedse sustituye (por el comando sustitución $(...)) después de in;
  2. La cadena resultante se expande a una lista de elementos;
  3. Cada elemento es, a su vez, asignado ssid_namee impreso por echo.

La ampliación en el punto 2 se realiza según el valor del separador de campo interno ( IFS), que por defecto es <space><tab><newline>. De este modo,tu soluciónfunciona porque permite fordividir la cadena sustituida solo en nuevas líneas.

Además de su respuesta, tenga en cuenta que $'\n'no es portátil, incluso si esa sintaxis ( $'string') es compatible con muchos shells.
No obstante, puedes utilizar una tarea como esta:

IFS='
'

Una construcción alternativa para procesar líneas de entrada es usar readen un whilebucle:

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

Aquí también, cada línea de sedla salida de 's se divide según el valor de IFS(que en este ejemplo se establece exactamente en la cadena nula para evitar cualquier efecto de división de palabras), pero las líneas se mantendrán separadas por readindependientemente de IFS.

Respuesta2

Es mejor usar un whilebucle con readen lugar de un forbucle.

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

ver tambiénhttps://mywiki.wooledge.org/BashFAQ/001

Respuesta3

Al agregar la siguiente línea en el código antes del bucle for, funciona perfectamente en mi caso.

IFS=$'\n'

información relacionada