bash:将 '\n' 分隔的字符串转换为数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24628076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash: convert '\n' delimited strings into array
提问by ramgorur
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 --
现在$names
变量包含用换行符分隔的字符串——
>_
(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 --
但问题是我无法通过索引(即${names[$i]
等)访问它们,如果我运行这个循环——
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 ?
任何的想法 ?
回答by Sanket Parmar
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.
设置IFS
。Shell 使用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
Output
输出
0: Netgear
1: Hon Hai Precision Ind. Co.
2: Apple
回答by firegurafiku
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:
让我为Sanket Parmar 的回答做出贡献。如果您可以将字符串拆分和处理提取到单独的函数中,则无需保存和恢复$IFS
—local
而是使用:
#!/bin/bash
function print_with_line_numbers {
local IFS=$'\n'
local lines=()
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:
也可以看看:
回答by Ale
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:
Bash 还有一个readarray
内置命令,可以在手册页中轻松搜索。它使用换行符 ( \n
) 作为默认分隔符和MAPFILE
默认数组,因此可以这样做:
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:
该-t
选项删除分隔符 ( '\n'
),以便它可以显式添加到printf
. 输出是:
0: Netgear
1: Hon Hai Precision Ind. Co.
2: Apple
回答by Hari Bharathi
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[@]}
正如其他人所说,IFS 会帮助你。IFS=$'\n' read -ra array <<< "$names"
如果您的变量有带空格的字符串,请将其放在双引号之间。现在您可以通过以下方式轻松获取数组中的所有值${array[@]}