我在一个目录中有 20 个感兴趣的文件。它们可以分为 5 组,每组由文件名中的 626 到 630 之间的数字标识。例如,可能(假设)有一个名为
the-quick-brown-fox-jumps-over-627-lazy-dogs_1_bbduk.fq
.
我想迭代每个组并将文件的路径临时存储为文本变量(与循环中的其他命令一起使用for
)。这就是我现在所拥有的:
for i in {626..630};do
fw1=$(/scratch/[username]/data/*"$i"-*_1_bbduk.fq)
fw2=$(/scratch/[username]/data/*"$i"_*_1_bbduk.fq)
rv1=$(/scratch/[username]/data/*"$i"-*_2_bbduk.fq)
rv2=$(/scratch/[username]/data/*"$i"_*_2_bbduk.fq)
done
问题:我得到了正确的路径(每个路径只有一个选项),但它显示“权限被拒绝”,并且我稍后似乎无法将该变量用作文本。看起来 bash 正在尝试执行它,这不是我想要的。
我尝试过在周围添加单引号(例如,,fw1='$(/scratch/[username]/data/*"$i"-*_1_bbduk.fq)'
但这会删除通配符。我考虑过双引号(“”),但我不确定如何使用它们而不弄乱“$i”变量。我已经尝试使用echo
(例如, fw1=echo $(/scratch/[username]/data/*"$i"-*_1_bbduk.fq)
但仍然存在“权限被拒绝”问题。
答案1
Bash 正在尝试执行文件名,因为您将每个文件都包含在
$( ... )
如果这不是您想要的,请使用:
for i in {626..630}; do
fw1=/scratch/[username]/data/*"$i"-*_1_bbduk.fq
fw2=/scratch/[username]/data/*"$i"_*_1_bbduk.fq
rv1=/scratch/[username]/data/*"$i"-*_2_bbduk.fq
rv2=/scratch/[username]/data/*"$i"_*_2_bbduk.fq
done
编辑:
根据您的评论,此代码可能是您想要的:
for i in {626..630}; do
fw1="$(compgen -G /scratch/[username]/data/*"$i"-*_1_bbduk.fq)"
fw2="$(compgen -G /scratch/[username]/data/*"$i"_*_1_bbduk.fq)"
rv1="$(compgen -G /scratch/[username]/data/*"$i"-*_2_bbduk.fq)"
rv2="$(compgen -G /scratch/[username]/data/*"$i"_*_2_bbduk.fq)"
done
答案2
吉姆正确识别您的代码存在问题,但是(IMO)更好的解决方案更接近您已有的解决方案:
fw1=(/划痕/用户名/data/*"$i"-*_1_bbduk.fq)
(注:没有$
)会给你一个与 glob 匹配的文件名数组。有点尴尬的${#fw1[@]}
是会告诉你数组中有多少个元素。例如,如果该数字是4
,则您可以使用
${fw1[0]}
、 ${fw1[1]}
和 ${fw1[2]}
来 ${fw1[3]}
访问这四个元素。但是 plain$fw1
会给你${fw1[0]}
,所以,如果你 110% 确定会有一个文件与每个模式匹配,你可以只使用简短的形式。
或者,你可以说
fw1=$(回显/划痕/用户名/data/*"$i"-*_1_bbduk.fq)
再说一次,你们很接近。 (但是,如果有可能存在多个与该模式匹配的文件,则数组解决方案会更好。)