我有一个包含很多图像的文件夹,名为“剪辑01234-randomlongstring.png“, 在哪里01234是一个随机的五位数字。我也有一个数组“剪辑编号" 带有整数列表。
现在我想创建一个列表“文件”,其中包含与“中的数字匹配的所有文件名”剪辑编号“数组。我该怎么做呢?
结果输出应该是我可以用与我创建的当前列表(所有文件)相同的方式处理的内容:
files=($(printf "%s\n" *.* | sort -V | tr '\n' ' '))
答案1
在循环中:
shopt -s nullglob
files=()
for number in "${clipnumbers[@]}"; do
printf -v pattern 'clip%s-*.png' "$number"
files+=( $pattern )
done
这会循环遍历数字并为每个数字创建一个文件名通配模式。该模式被扩展以将与其匹配的文件名添加到数组中files
。 shellnullglob
选项使不匹配的模式展开为空(而不是保持未展开)。
使用find
(用于递归到当前目录下的所有目录,并对每个找到的文件执行某些操作):
patterns=()
for number in "${clipnumbers[@]}"; do
printf -v pattern 'clip%s-*.png' "$number"
patterns+=( -o -name "$pattern" )
done
find . -type f \( "${patterns[@]:1}" \) -exec action-to-perform-on-files {} \;
从扩展中的列表中删除:1
首字母。-o
patterns
这将搜索文件与对文件执行某些操作结合起来。它会失败如果您的clipnumbers
数组包含数千个数字(参数列表会变得太长)。
答案2
选项1
如同拘萨罗南达的回答但使用数组扩展而不是循环:
设置
$ touch clip12710-x.png clip30443-x.png clip57592-x.png clip76672-x.png clip93493-x.png
$ declare -a array=([0]="30443" [1]="76672" [2]="42424")
请注意,该数组仅包含两个预期匹配的项目;有些文件名的剪辑是不是存在并且有剪辑编号array
存在并且其中不是作为文件名存在。
执行
$ shopt -s nullglob
$ pfiles=( "${array[@]/#/clip}" )
$ oIFS="$IFS"
$ IFS=
$ pfiles=( ${pfiles[@]/%/-*.png} )
$ IFS="$oIFS"
$ declare -p pfiles
declare -a pfiles=([0]="clip30443-x.png" [1]="clip76672-x.png")
请注意,第一个赋值中小心地包含了双引号,而第二个赋值中则没有双引号。初始分配将数字的“array”数组转换为部分文件名的“pfiles”数组:前置字符串clip
每个元素的。第二次作业追加-*.png
数组中每个元素的通配符;此赋值中缺少引号允许 shell 拆分每个元素$IFS
(通常是空格、制表符和换行符),但我们暂时将 IFS 覆盖为空。然后 shell 还会“globs”结果,这就是我们在这里想要的——它将“clip...*-png”名称扩展为任何匹配的文件名。设置 shell 选项后nullglob
,任何不匹配的通配符都会被删除。最终结果是 pfiles 中与原始数组中的剪辑编号相匹配的文件数组。
选项#2
(虐待扩展的通配符:
shopt -s extglob nullglob
declare -a array=([0]="30443" [1]="76672" [2]="42424")
oIFS="$IFS"
IFS='|'
p="${array[*]}"
IFS="$oIFS"
pfiles=( clip@($p)-*.png )
这是通过将 IFS 设置为管道符号来实现的|
,以便后续对p
of 的赋值array[*]
连接 by 管道的元素array
(此时 $IFS 的第一个字符)。管道是 bash 的扩展通配语法在扩展通配模式中的选项之间所需的分隔符。最后一行扩展为与我们构建的扩展 glob 模式匹配的文件数组:
- 从...开始
clip
- 包含给定模式之一(剪辑编号),现在包含在变量中
p
- 然后是
-
任何东西 - 并结束于
.png
nullglob
如果您的剪辑数组不与任何现有文件名重叠,则需要 shell 选项。
答案3
和zsh
:
clipnumbers=(01234 33333)
files=(clip$^clipnumbers-*.png(N.))
这会为每个剪辑编号扩展一个 glob。或者,您可以将数组转换为全局交替运算符:
files=(clip(${(j:|:)~clipnumbers})-*.png(N.))
答案4
mapfile -t files < <( shopt -s nullglob ; printf "%s\n" $(printf "clip%s-*.png " "${clipnumbers[@]}" ) )
mapfile -t files
将行作为数组读入文件,去掉尾随换行符。shopt -s nullglob
将不存在的模式扩展为空字符串printf "%s\n" ...
展开模式,每行一个。$(printf "clip%s-*.png " "${arr[@]}") )
构建模式。