1

私はこのファイルを持っています

Seq1
10 1 5
10 2 6
10 3 9
Seq2
15 2 7
15 4 9
15 8 12

次のように、各 Seq (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 ループから抜け出しません。この愚かな人間に手を差し伸べてください:(

4

3 に答える 3

1

標準入力でネストされた読み取り呼び出しを使用するネストされたループの代わりに、単一のループを使用するように再構築します。

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 ファイル ハンドルが供給されたときにおそらくブロックされている内部読み取り呼び出しの問題が回避されます。

于 2012-12-01T10:54:41.253 に答える
1
  • のカーソル行を変更することはできません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*}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
于 2012-12-01T11:47:13.383 に答える
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[@]}
于 2012-12-01T10:47:31.303 に答える