我想做这个:readarray var1 < <(find "/path/to/dir" \( $var2 \) | sort)
echo $var2
user@domain:~# -name "*.avi" -o -name "*.mkv"
不幸的是,我的脚本不起作用。请告诉我我哪里做错了。
答案1
使用数组:
var2=( -name "*.avi" -o -name "*.mkv" )
readarray var1 < <(find "/path/to/dir" \( "${var2[@]}" \) | sort)
看看有些相关的我们如何运行存储在变量中的命令?
答案2
要将路径下的所有名称/path/to/dir
作为排序列表获取bash
:
shopt -s globstar nullglob dotglob
names=( /path/to/dir/** )
中的shellglobstar
选项bash
允许使用**
glob,其工作方式与路径名类似,*
但在路径名中进行匹配/
(即,它“递归地”向下匹配目录)。 shellnullglob
选项使得如果 shell glob 这样做不是匹配任何名称,它将被完全删除(默认是保留未展开的模式)。该dotglob
选项会导致默认情况下匹配隐藏文件名。
shell glob 的结果扩展是按字典顺序排列的,就像 的默认输出一样,因此不需要sort
通过管道传输名称。sort
.avi
要获取具有文件名后缀或 的名称.mkv
,请使用
shopt -s globstar nullglob dotglob extglob
names=( /path/to/dir/**/*.@(avi|mkv) )
在这里,我添加了extglob
shell 选项,它允许使用扩展的通配模式。该模式的@(avi|mkv)
意思是“或者avi
” mkv
,因此完整的模式将匹配下面以或者/path/to/dir
结尾的任何名称。结果数组将被排序。.avi
.mkv
find
如果您需要使用找到的名称执行操作,或者需要合并特定的文件类型测试,这将很有用。例如,如果您需要确保仅匹配常规文件, 使用
find /path/to/dir -type f \( -name '*.avi' -o -name '*.mkv' \)
给定两个文件名后缀avi
和mkv
一个名为 的数组suffix
,-name
测试可以构造为一个数组:
suffix=( avi mkv )
nametest=( -false ) # assumes GNU find here
for suf in "${suffix[@]}"; do
nametest+=( -o -name ".$suf" )
done
find /path/to/dir -type f \( "${nametest[@]}" \)
保存几乎永远不会正确输出当你真正想要的时候,在find
变量中做事到找到的名字。相反,使用-exec
来执行操作:
find /path/to/dir -type f \( "${nametest[@]}" \) -exec sh -c '
for pathname do
# do something with "$pathname" here
done' sh {} +
如需进一步阅读,请参阅
- 了解“find”的 -exec 选项
- 为什么循环查找的输出是不好的做法?
- 有关的许多其他问题和答案寻找在这个网站上。