【问题标题】:Merging files in folder with same file name except one character合并文件夹中除一个字符外具有相同文件名的文件
【发布时间】:2018-10-21 13:30:56
【问题描述】:

我的文件名如下:

fastqs/hgmm_100_S1_L001_R1_001.fastq.gz
fastqs/hgmm_100_S1_L002_R1_001.fastq.gz
fastqs/hgmm_100_S1_L003_R1_001.fastq.gz

fastqs/hgmm_100_S1_L001_R2_001.fastq.gz
fastqs/hgmm_100_S1_L002_R2_001.fastq.gz
fastqs/hgmm_100_S1_L003_R2_001.fastq.gz

并且我想将它们合并到上面显示的组中,从而允许合并 LXXX。

我可以这样做:

cat fastqs/hgmm_100_S1_L00?_R1_001.fastq.gz > data/hgmm_100_S1_R1_001.fastq.gz
cat fastqs/hgmm_100_S1_L00?_R2_001.fastq.gz > data/hgmm_100_S1_R2_001.fastq.gz

但这需要我对每个文件组进行硬编码。如何设置它以便将所有 L 值合并到一个组中并输出与输入文件名相同的文件,只是没有L?

谢谢, 杰克

编辑:

很抱歉没有在原始帖子中包含此内容,但如果我有类似的内容怎么办:

fastqs/hgmm_100_S1_L001_R1_001.fastq.gz
fastqs/hgmm_100_S1_L002_R1_001.fastq.gz
fastqs/hgmm_100_S1_L003_R1_001.fastq.gz

fastqs/hgmm_200_S1_L001_R2_001.fastq.gz
fastqs/hgmm_200_S1_L002_R2_001.fastq.gz
fastqs/hgmm_200_S1_L003_R2_001.fastq.gz

(只有变化才是最开始(100 -> 200))

这将如何工作?本质上,我想合并这些文件,只要名称的所有部分,除了 L ???是相同的。

【问题讨论】:

  • @Socowi 我的错!我会解决这个问题。
  • 您必须对 something 进行硬编码,并且不清楚界限是什么。公平地说,您希望外部循环遍历 L 和三个数字的唯一序列吗?
  • @tripleee 是的,L+3 位在文件名之间允许不同,但文件名的其余部分必须相同才能合并标准。
  • 当您寻求代码方面的帮助时,通常会包含您的代码。你试过什么了?你的结果是什么?

标签: bash unix merge cat fastq


【解决方案1】:

如果_L###_ 模式只存在于文件名的那一部分,您可以尝试如下操作:

#!/usr/bin/env bash

# Define an associative array. Requires bash 4+
declare -A a

# Use extended glob notation. Read the man page or this.
shopt -s extglob

# Collect the file patterns by writing indexes in the array.
for f in fastqs/*_L+([0-9])_*.fastq.gz; do
  a["${f/_L+([0-9])_/_*_}"]=1
done

# And finally, gather your files.
for f in "${!a[@]}"; do
  # Strip any existing directory part of the filename to build our target
  target="data/${f##*/}"
  # Concatenate files matching the glob into our intended target
  cat $f > "${target/[*]_/}"
done
  • 我们使用模式替换将每个文件规范的可变部分转换为一个 glob。
  • 我们使用关联数组的索引,因为它可以轻松保持唯一列表。
  • ${! 让我们可以逐步遍历数组的索引而不是其值。

【讨论】:

  • 如何将输出文件写入不同的目录? /数据在示例中。谢谢!
  • 您没有包含任何试图将文件放入不同目录的代码。但是您可以使用参数扩展剥离$f 的现有目录部分,然后添加新的目标目录。当然,它需要额外的行来分配变量,因为您一次只能进行一个参数扩展。
【解决方案2】:

您可以即时进行分组。遍历所有文件并将它们附加到它们的分组文件中。 *? 以排序方式展开,所以顺序应该是正确的。

cd fastqs
for f in *_L???_*fastq.gz; do
    cat "$f" >> "../data/${f/_L???_/_}"
done
cd ..

由于总是附加文件,因此您应该在再次运行此命令之前清除您的 data/ 目录。

【讨论】:

  • 非常感谢!在写问题的时候,我忽略了一种情况,那就是名字的开头不一定一致。您能否建议如何处理我在上面的编辑中添加的案例?再次感谢:)
  • 那么你最好选择三个选项中的最后一个。您只需调整 glob 模式,以便匹配您想要包含的所有文件。见编辑。
猜你喜欢
  • 2017-06-18
  • 1970-01-01
  • 2013-10-10
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多