15

我在目录中列出文件并循环遍历它们,但我也需要知道有多少。${#dirlist[@]} 始终为 1,但 for 循环有效吗?

#!/bin/bash
prefix="xxx"; # as example

len=${#prefix}; # string length
dirlist=`ls ${prefix}*.text`;
qty=${#dirlist[@]};  # sizeof array is always 1
for filelist in $dirlist
do
    substring="${filelist:$len:-5}";
    echo "${substring}/${qty}";
done

我有文件 xxx001.text 到 xxx013.text
但我得到的只是 001/1 002/1 003/1

4

5 回答 5

37

这:

dirlist=`ls ${prefix}*.text`

不做数组。它只生成一个带有空格分隔文件名的字符串。

你所要做的

dirlist=(`ls ${prefix}*.text`)

使其成为一个数组。

然后$dirlist将仅引用第一个元素,因此您必须使用

${dirlist[*]}

在循环中引用所有这些。

于 2013-03-05T13:15:27.200 回答
3

除非您将其包围,否则您不会创建数组( )

dirlist=(`ls ${prefix}*.text`)
于 2013-03-05T13:08:21.353 回答
3

声明一个文件数组:

arr=(~/myDir/*)

使用计数器遍历数组:

for ((i=0; i < ${#arr[@]}; i++)); do

  # [do something to each element of array]

  echo "${arr[$i]}"
done
于 2016-05-02T06:04:30.090 回答
2
dir=/tmp
file_count=`ls -B "$dir" | wc -l`
echo File count: $file_count
于 2013-03-05T13:08:45.223 回答
0

中的数组语法bash很简单,使用括号()

# string
var=name

# NOT array of 3 elements
# delimiter is space ' ' not ,
arr=(one,two,three) 
echo ${#arr[@]}
1

# with space
arr=(one two three)
# or ' ',
arr=(one, two, three)
echo ${#arr[@]}
3

# brace expansion works as well
# 10 elements
arr=({0..9})
echo ${#arr[@]}
10

# advanced one
curly_flags=(--{ftp,ssl,dns,http,email,fc,fmp,fr,fl,dc,domain,help});
echo ${curly_flags[@]}
--ftp --ssl --dns --http --email --fc --fmp --fr --fl --dc --domain --help
echo ${#curly_flags[@]}
12

如果要运行命令并存储输出

# a string of output
arr=$(ls)
echo ${#arr[@]}
1

# wrapping with parentheses
arr=($(ls))
echo ${#arr[@]}
256

一种更高级/更方便的方法是使用内置的bash 命令mapfilereadarray进程替换。这是一个使用示例mapfile

# read the output of ls, save it in the array name: my_arr
# -t    Remove a trailing DELIM from each line read (default newline)
mapfile -t my_arr < <(ls)
echo ${#my_arr[@]}
256
于 2021-03-16T09:12:22.530 回答