i have this file
Seq1
10 1 5
10 2 6
10 3 9
Seq2
15 2 7
15 4 9
15 8 12
i want to have arrays for each Seqs (Seq1, Seq2) like this:
2ndColumn=(1,2,3)
3rdColumn=(5,6,9)
i wrote this but it does not break the while loop..
#!/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
this script will iterate forever, it does not get out of while loop. please give a hand to this stupid humanbeing :(
I would restructure it to use a single loop instead of a nested loop with nested read calls on 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
This will avoid issues with the inner read call, which is probably being blocked when fed a stdin file handle.
while read
I wrote this for you with a little hack to prefix the array names with 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"
OUTPUT
seq1_2ndColumn seq1_3rdColumn seq2_2ndColumn seq2_3rdColumn arrays are declared
EXPLANATIONS
${!pattern*}
is a nice feature of bash to display variables beginning with pattern (( ))
is an arithmetic command, which returns an exit status of 0 if the expression is nonzero, or 1 if the expression is zero. Also used as a synonym for "let", if side effects (assignments) are needed. See http://mywiki.wooledge.org/ArithmeticExpressionBONUS
If you have the control on what's in your array, try doing this at the end ::
for s in ${!seq*}; do
printf '\t%s\n' $(eval echo \${$s[@]})
done
See See http://mywiki.wooledge.org/BashFAQ/048
new OUTPUT
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[@]}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.