【发布时间】:2022-01-19 01:02:17
【问题描述】:
我正在尝试在 bash 中创建一个 for 循环/while 循环,它使用两个不同的文件(具有相同的前缀)。例如:
/home/samples - 包含文件 A-anything.fq B-anything.fq 等
/home/annotation - 包含文件 A-anything2.tab B-anything2.tab 等
我在两个单独的数组中称呼他们的名字:
filepathsfq=( /home/samples/*fq )
filenamesfq=( "${filepathsfq[@]##*/}" ) #create an array so no
meta-characters in file name mess with anything
filepathstab=( /home/anottation/*tab )
filenamestab=("${filepathstab[@]##*/}")
我正在尝试创建一个双列数组,例如 filenamesfq 和 filenamestab 基于字符串的前 10 个字符的 MATCH 进行配对(在我的情况下,这足以进行完整的文件配对,因为 10第一个字符是文件标识符)。
例如:
A12345689-anything.fq A12345689-anything2.tab
B12345689-anything.fq B12345689-anything2.tab
我试过了
declare -a a0=("${filepathsfq[@]##*/}")
declare -a a1=("${filepathstab[@]##*/}")
这确实有效,但我不能将一个 for 循环中的数组作为一个变量调用
我想要这个“配对数组”,因为我正在尝试运行一个 for 循环,它需要只能接受一个变量。所以这个变量必须包含所有成对的名字。
我什至不知道如何根据前 10 个字符开始配对名称。我一直通过将值导出到 CSV 文件,然后使用公式匹配 excel 中的前 10 个字符来做到这一点,这不是很好。
我也用过:
paste -d, <(printf '%s\n' "${filepathsfq[@]##*/}") <(printf '%s\n' "${filepathstab[@]##*/}") >> samples.csv
要创建 CSV 文件,请手动验证所有内容是否正确配对,然后:
while IFS="," read fq tab
do
echo $fq, $tab
done < samples.csv
上面的代码可用于预期目的,但需要外部验证以进行名称匹配。我不知道如何匹配文件名并将其转换为数组并在 for 循环或 while 循环中使用它
【问题讨论】:
-
有些边界情况你解释得不够清楚: 1) 当有
C.fq但没有C.tab时会发生什么? 2) 为什么只有前 10 个字符而不是整个前缀?您可能会得到AC.fq与A.tab配对和A.fq与AC.tab配对;你需要随机配对吗? -
@GabrielG:光说我试过是不够的;您需要展示您实际尝试过的内容,以便我们可以看到您卡在哪里。我也不知道变量变成数组是什么意思。您通常不会在数组和标量之间来回更改变量的类型,而是从一开始就决定变量应该是数组还是标量。
-
@Fravadona,在我的具体情况下,10 个字符足以保证没有一个文件是相同的!例如,对于没有“对”的情况,我会创建一个 if 条件来将失败的文件导出到 txt。我还添加了一些我尝试过但没有成功的东西。
-
我不明白,最终目标是什么?
Which will output the paired values in the CSV file太好了!所以它有效。那你为什么写在这里?你的问题是什么?but need external validation for the pairing什么意思?I don't even know how to start pairing the names与paste完全相同,但cut -c-10的名称为 10 个字符。另外,如果两个目录中的文件名相同,为什么不只使用一个目录呢? -
@GabrielG。更新了我的答案,应该足够清楚如何使用了