【问题标题】:Creating paired array based on file name prefix match in bash在bash中基于文件名前缀匹配创建配对数组
【发布时间】: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[@]##*/}")

我正在尝试创建一个双列数组,例如 filenamesfqfilenamestab 基于字符串的前 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.fqA.tab 配对和A.fqAC.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 namespaste 完全相同,但 cut -c-10 的名称为 10 个字符。另外,如果两个目录中的文件名相同,为什么不只使用一个目录呢?
  • @GabrielG。更新了我的答案,应该足够清楚如何使用了

标签: arrays bash prefix


【解决方案1】:

给定两个目录:

/home/samples
|-- A12345689-anything.fq
|-- B12345689-anything.fq
|-- C12345689-anything0.fq
|-- C12345689-anything1.fq
`-- D12345689-anything.fq

/home/annotation
|-- A12345689-anything2.tab
|-- B12345689-anything2.tab
|-- C12345689-anything2.tab
`-- E12345689-anything2.tab

以下 bash 代码:

#!/bin/bash

shopt -s nullglob

fq_dirpath=/home/samples
tab_dirpath=/home/annotation

for fq_filepath in "$fq_dirpath"/*.fq
do
    prefix=${fq_filepath##*/}
    prefix=${prefix:0:10}

    fq_filepaths=( "$fq_dirpath"/"$prefix"*.fq )
    tab_filepaths=( "$tab_dirpath"/"$prefix"*.tab )

    # sanity checks
    [ ${#fq_filepaths[@]} -eq 1 ] || continue
    [ ${#tab_filepaths[@]} -eq 1 ] || continue

    fq_filename=${fq_filepaths##*/}
    tab_filename=${tab_filepaths##*/}

    # process the pair
    printf '%s %s\n' "$fq_filename" "$tab_filename"
done

shopt -u nullglob

输出:

A12345689-anything.fq A12345689-anything2.tab
B12345689-anything.fq B12345689-anything2.tab

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多