我有这个文件
Seq1
10 1 5
10 2 6
10 3 9
Seq2
15 2 7
15 4 9
15 8 12
我希望每个Seqs(Seq1,Seq2)都有这样的数组:
2ndColumn=(1,2,3)
3rdColumn=(5,6,9)
我写了这个,但它没有打破while循环..
#!/bin/bash
2ndColumn=()
3rdColumn=()
while read line
do
if [[ $line == S* ]]
echo "$line"
else
i=0
while [[ $line != S* ]]
do
2ndColumn[i]="$(echo $line | cut -d\ -f2)"
3rdColumn[i]="$(echo $line | cut -d\ -f3)"
i=$((i+1))
read line
done
echo "${2ndColumn[@]} and ${3rdColumn[@]}"
fi
done < file
exit 0
这个脚本将永远迭代,它不会退出while循环。请帮助这个愚蠢的人类:(
答案 0 :(得分:1)
我会重构它以使用单个循环而不是嵌套循环,并在stdin上嵌套读取调用:
2ndColumn=()
3rdColumn=()
i=0
while read line
do
if [[ $line == S* ]]
echo "$line ==> ${2ndColumn[@]} and ${3rdColumn[@]}"
# reset the lists...
2ndColumn=()
3rdColumn=()
i=0
else
2ndColumn[i]="$(echo $line | cut -d\ -f2)"
3rdColumn[i]="$(echo $line | cut -d\ -f3)"
i=$((i+1))
fi
done
这将避免内部读取调用的问题,这可能在提供stdin文件句柄时被阻止。
答案 1 :(得分:1)
while read
我用一点hack为你写了这个,为数组名称添加seq N+1
前缀:
#!/bin/bash
file=file.txt
while read line; do
if [[ $line == S* ]]; then
echo "$line"
i=0
((Seq++))
else
declare seq${Seq}_2ndColumn[i]="$(echo $line | cut -d\ -f2)"
declare seq${Seq}_3rdColumn[i]="$(echo $line | cut -d\ -f3)"
((i++))
fi
done < "$file"
echo "${!seq*} arrays are declared"
<强>输出强>
seq1_2ndColumn seq1_3rdColumn seq2_2ndColumn seq2_3rdColumn arrays are declared
<强>说明强>
${!pattern*}
是bash的一个很好的功能,用于显示以 pattern 开头的变量(( ))
是一个算术命令,如果表达式非零,则返回退出状态0;如果表达式为零,则返回1。如果需要副作用(赋值),也用作“let”的同义词。请参阅http://mywiki.wooledge.org/ArithmeticExpression <强>奖金强>
如果您可以控制数组中的内容,请尝试在结尾处执行此操作::
for s in ${!seq*}; do
printf '\t%s\n' $(eval echo \${$s[@]})
done
请参阅http://mywiki.wooledge.org/BashFAQ/048
新输出
seq1_2ndColumn
1
2
3
seq1_3rdColumn
5
6
9
seq2_2ndColumn
2
4
8
seq2_3rdColumn
7
9
12
答案 2 :(得分:0)
file=/PATH/TO/file.txt
arr1=( $(awk '/^Seq/{l++} l==1{print $2}' "$file") )
arr2=( $(awk '/^Seq/{l++} l==1{print $3}' "$file") )
echo "arr1:"
printf '\t%s\n' ${arr1[@]}
echo "arr2:"
printf '\t%s\n' ${arr2[@]}