Bash: конвертировать '\n' разделимые строки в массив

У меня есть этот script -

nmapout=`sudo nmap -sP 10.0.0.0/24`
names=`echo "$nmapout" | grep "MAC" | grep -o '(.\+)'`
echo "$names"

теперь переменная $names содержит строки, разделенные символами новой строки -

>_
 (Netgear)
 (Hon Hai Precision Ind. Co.)
 (Apple)

Я попытался сделать преобразование массива с подстрочным подходом -

names=(${names//\\n/ })
echo "${names[@]}"

Но проблема в том, что я не могу получить к ним доступ путем индексирования (т.е. ${names[$i] и т.д.), если я запустил этот цикл -

for (( i=0; i<${#names[@]}; i++ ))
do
     echo "$i: ${names[$i]"
     # do some processing with ${names[$i]}
done

Я получаю этот вывод -

>_
 0: (Netgear)
 1: (Hon
 2: Hai

но я хочу -

>_
 0: (Netgear)
 1: (Hon Hai Precision Ind. Co.)
 2: (Apple)

Я не мог понять, как это сделать, обратите внимание, что во второй строке есть пробелы.

Любая идея?

Ответ 1

Установите IFS. Оболочка использует переменную IFS для определения разделителей полей. По умолчанию IFS установлен на пробел. Измените это на новую строку.

#!/bin/bash
names="Netgear
Hon Hai Precision Ind. Co.
Apple"

SAVEIFS=$IFS   # Save current IFS
IFS=$'\n'      # Change IFS to new line
names=($names) # split to array $names
IFS=$SAVEIFS   # Restore IFS

for (( i=0; i<${#names[@]}; i++ ))
do
    echo "$i: ${names[$i]}"
done

Выход

0: Netgear
1: Hon Hai Precision Ind. Co.
2: Apple

Ответ 2

Позвольте мне внести свой вклад в ответ Sanket Parmar. Если вы можете извлечь разделение и обработку строк в отдельную функцию, нет необходимости сохранять и восстанавливать $IFS - использовать local вместо:

#!/bin/bash

function print_with_line_numbers {
    local IFS=$'\n'
    local lines=($1)
    local i
    for (( i=0; i<${#lines[@]}; i++ )) ; do
        echo "$i: ${lines[$i]}"
    done
}

names="Netgear
Hon Hai Precision Ind. Co.
Apple"

print_with_line_numbers "$names"

См. также:

Ответ 3

Как говорили другие, IFS поможет вам. IFS=$'\n' read -ra array <<< "$names" если в вашей переменной есть строка с пробелами, поместите ее в двойные кавычки. Теперь вы можете легко получить все значения в массиве с помощью ${array[@]}