我需要逐行读取文件,并将每一行用“,”分隔,然后存储到数组中。
文件源文件。
usl-coop,/root
usl-dev,/bin
脚本。
i=1
while read -r line; do
IFS="," read -ra para_$i <<< $line
echo ${para_$i[@]}
((i++))
done < source_file
预期的输出。
para_1[0]=usl-coop
para_1[1]=/root
para_2[0]=usl-dev
para_2[1]=/bin
脚本将输出有关回声的错误。
./sofimon.sh: line 21: ${para_$i[@]}: bad substitution
例如,当我逐一回显数组时
echo para_1[0]
它表明已存储变量。
但是我需要将它与变量一起使用,像这样。
${para_$i[1]}
可以这样做吗?
谢谢。
S。
答案 0 :(得分:3)
有一个技巧可以使用associative arrays模拟2D数组。它效果很好,我认为是最灵活和可扩展的:
declare -A para
i=1
while IFS=, read -r -a line; do
for j in ${!line[@]}; do
para[$i,$j]="${line[$j]}"
done
((i++)) ||:
done < source_file
declare -p para
将输出:
declare -A para=([1,0]="usl-coop" [1,1]="/root" [2,1]="/bin" [2,0]="usl-dev" )
无需修改脚本,您可以使用indirect variable expansion。有时在更简单的脚本中使用:
i=1
while IFS="," read -r -a para_$i; do
n="para_$i[@]"
echo "${!n}"
((i++)) ||:
done < source_file
declare -p ${!para_*}
或与 nameref a named reference to another variable基本相同(注意:请参见[@]
在间接扩展中如何成为变量的一部分,而在命名引用中则不然) :
i=1
while IFS="," read -r -a para_$i; do
declare -n n
n="para_$i"
echo "${n[@]}"
((i++)) ||:
done < source_file
declare -p ${!para_*}
以上两个脚本都将输出相同的内容:
usl-coop /root
usl-dev /bin
declare -a para_1=([0]="usl-coop" [1]="/root")
declare -a para_2=([0]="usl-dev" [1]="/bin")
也就是说,我认为您根本不应该将文件读入内存。这只是一个糟糕的设计。 Shell和bash的建立是围绕使用管道,流,fifo,重定向,进程替换等传递文件而无需保存/复制/存储文件。如果有要解析的文件,则应将其流式传输到另一个进程,解析并保存结果,而不必将整个输入存储在内存中。如果要在文件中查找某些数据,请使用grep
或awk
。
答案 1 :(得分:0)
这是一个简短的awk
脚本,可以完成任务。
awk 'BEGIN{FS=",";of="para_%d[%d]=%s\n"}{printf(of, NR, 0, $1);printf(of, NR, 1, $2)}' input.txt
提供所需的输出。
说明:
BEGIN{
FS=","; # set field seperator to `,`
of="para_%d[%d]=%s\n" # define common printf output format
}
{ # for each input line
printf(of, NR, 0, $1); # output for current line, [0], left field
printf(of, NR, 1, $2) # output for current line, [1], right field
}