I have this script --
nmapout=`sudo nmap -sP 10.0.0.0/24`
names=`echo "$nmapout" | grep "MAC" | grep -o '(.\+)'`
echo "$names"
now the $names
variable contains strings delimited with newlines --
>_
(Netgear)
(Hon Hai Precision Ind. Co.)
(Apple)
I tried to do the array conversion with the sub-string approach --
names=(${names//\\n/ })
echo "${names[@]}"
But the problem is that I can't access them by indexing (i.e. ${names[$i]
etc), if I run this loop --
for (( i=0; i<${#names[@]}; i++ ))
do
echo "$i: ${names[$i]"
# do some processing with ${names[$i]}
done
I get this output --
>_
0: (Netgear)
1: (Hon
2: Hai
but what I want is --
>_
0: (Netgear)
1: (Hon Hai Precision Ind. Co.)
2: (Apple)
I could not figure out a good way to do this, please note that the second string has spaces in it.
Any idea ?
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
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:
- Setting IFS for a single statement