[英]Bash- parse file into arrays
我有这个文件
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 循环。 请帮帮这个愚蠢的人类:(
我会重构它以使用单个循环而不是在 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
这将避免内部读取调用的问题,当提供标准输入文件句柄时,内部读取调用可能会被阻止。
while read
的光标行我为你写了一个小技巧,用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 的一个很好的功能,可以显示以模式开头的变量(( ))
是一个算术命令,如果表达式非零,则返回退出状态 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
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[@]}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.