Zsh:读取从文件到数组的行

时间:2012-09-29 08:57:13

标签: arrays file-io zsh

我正在尝试将文件作为一个行数组读入然后遍历它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

这样做更简单的方法是什么?我还需要计算文件中的行数。

2 个答案:

答案 0 :(得分:11)

#!/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++ ))
endfor

你的代码中有一些奇怪的东西:

  1. 为什么每次都要分割LIST而不是将它变成数组变量?这只是浪费CPU时间。
  2. 为什么不使用for ITEM in ${(f)LIST}
  3. 有可能直接询问zsh关于数组长度:$#ARRAY。无需确定最后一个元素的索引。
  4. POS在代码中获得与SIZE相同的值。因此它只会迭代一次。
  5. 括号可能是因为3:(I)与模式匹配的问题。阅读文档。

答案 1 :(得分:6)

我知道自问题得到解答以来已经有很多时间,但我认为值得发布一个更简单的答案(不需要zsh / mapfile外部模块):< / p>

#!/bin/zsh
for line in "${(@f)"$(</path/to/some/file.txt)"}"
{
  // do something with each $line
}