7

ファイルを行の配列として読み込んでから、zshで反復しようとしています。入力ファイルに特定の文字 (括弧など) が含まれている場合を除いて、私が取得したコードはほとんどの場合機能します。これがそのスニペットです:

#!/bin/zsh
LIST=$(cat /path/to/some/file.txt)
SIZE=${${(f)LIST}[(I)${${(f)LIST}[-1]}]}
POS=${${(f)LIST}[(I)${${(f)LIST}[-1]}]}
while [[ $POS -le $SIZE ]] ; do
    ITEM=${${(f)LIST}[$POS]}
    # Do stuff
    ((POS=POS+1))
done

適切に機能させるには、何を変更する必要がありますか?

4

3 に答える 3

17
#!/bin/zsh
zmodload zsh/mapfile
FNAME=/path/to/some/file.txt
FLINES=( "${(f)mapfile[$FNAME]}" )
LIST="${mapfile[$FNAME]}" # Not required unless stuff uses it
integer POS=1             # Not required unless stuff uses it
integer SIZE=$#FLINES     # Number of lines, not required unless stuff uses it
for ITEM in $FLINES
    # Do stuff
    (( POS++ ))
done

コードに奇妙なことがいくつかあります。

  1. LIST配列変数にするのではなく、毎回分割するのはなぜですか? これは単に CPU 時間の無駄です。
  2. なぜあなたは使わないのですfor ITEM in ${(f)LIST}か?
  3. 配列の長さについて zsh に直接問い合わせる可能性があります: $#ARRAY. 最後の要素の最後の出現のインデックスを決定する必要はありません。
  4. POSコードと同じ値を取得SIZEします。したがって、1 回だけ反復します。
  5. (I)3.:がパターンに一致するため、括弧が問題になる可能性があります。ドキュメントを読んでください。
于 2012-09-29T11:23:34.030 に答える
14

質問に回答してからかなりの時間が経過していることは知っていますが、より簡単な回答を投稿する価値があると思います(zsh/mapfile外部モジュールは必要ありません):

#!/bin/zsh
for line in "${(@f)"$(</path/to/some/file.txt)"}"
{
  // do something with each $line
}
于 2016-12-18T20:56:38.730 に答える