I have this script:
nmapout=`sudo nmap -sP 10.0.0.0/24`
names=`echo "$nmapout" | grep "MAC" | grep -o \'(.\\+)\'`
echo "$names"
Bash also has a readarray
builtin command, easily searchable in the man page. It uses newline (\n
) as the default delimiter, and MAPFILE
as the default array, so one can do just like so:
names="Netgear
Hon Hai Precision Ind. Co.
Apple"
readarray -t <<<$names
printf "0: ${MAPFILE[0]}\n1: ${MAPFILE[1]}\n2: ${MAPFILE[2]}\n"
The -t
option removes the delimiter ('\n'
), so that it can be explicitly added in printf
. The output is:
0: Netgear
1: Hon Hai Precision Ind. Co.
2: Apple
As others said, IFS will help you.IFS=$'\n' read -ra array <<< "$names"
if your variable has string with spaces, put it between double quotes.
Now you can easily take all values in a array by ${array[@]}
Let me contribute to Sanket Parmar's answer. If you can extract string splitting and processing into a separate function, there is no need to save and restore $IFS
— use local
instead:
#!/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"
See also:
Set IFS
. Shell uses IFS
variable to determine what the field separators are. By default IFS
is set to the space character. Change it to newline.
#!/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
Output
0: Netgear
1: Hon Hai Precision Ind. Co.
2: Apple