bash在这里有一些奇怪的行为。我有几个文件,其中一些是在多个部分。每个名为*_Rx_00y.fastq.gz的文件应该与x连接作为标识符,即R1_001和R1_002(以及假设的R1_003)放在一起。
[mark@theNosebook Sample_P4]$ ls -lh
total 822M
-rwxr-xr-x 1 mark mark 404M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R1_001.fastq.gz
-rwxr-xr-x 1 mark mark 2.6M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R1_002.fastq.gz
-rwxr-xr-x 1 mark mark 414M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R2_001.fastq.gz
-rwxr-xr-x 1 mark mark 2.6M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R2_002.fastq.gz
-rwxr-xr-x 1 mark mark 144 Aug 13 12:25 SampleSheet.csv
我希望将两个*_R1_00x.fastq.gz文件连接到第一个文件。我意识到我可以在这里用>>
,但是如果我有超过2个元素的话,它看起来很笨拙。我的解决方案,我认为应该工作是:
name=$(ls *_R1_001.fastq.gz)
cat $(ls *_R1_*) > ${name}
但是,这里我得到
[mark@theNosebook Sample_P4]$ ls -lh
total 421M
-rwxr-xr-x 1 mark mark 2.6M Aug 13 12:37 P4_CTCTCTAC-AGAGTAGA_L002_R1_001.fastq.gz
-rwxr-xr-x 1 mark mark 2.6M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R1_002.fastq.gz
-rwxr-xr-x 1 mark mark 414M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R2_001.fastq.gz
-rwxr-xr-x 1 mark mark 2.6M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R2_002.fastq.gz
-rwxr-xr-x 1 mark mark 144 Aug 13 12:25 SampleSheet.csv
注意,结果输出的大小仅为第二个文件的大小(2.6M)。将它们写入一个单独的文件,这里是cat,效果很好。
[mark@theNosebook Sample_P4]$ cat $(ls *_R1_*) > cat
[mark@theNosebook Sample_P4]$ ls -lh
total 1.2G
-rw-r--r-- 1 mark mark 407M Aug 13 12:36 cat
-rwxr-xr-x 1 mark mark 404M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R1_001.fastq.gz
-rwxr-xr-x 1 mark mark 2.6M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R1_002.fastq.gz
-rwxr-xr-x 1 mark mark 414M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R2_001.fastq.gz
-rwxr-xr-x 1 mark mark 2.6M Aug 13 12:25 P4_CTCTCTAC-AGAGTAGA_L002_R2_002.fastq.gz
-rwxr-xr-x 1 mark mark 144 Aug 13 12:25 SampleSheet.csv
这是怎么回事?我想保留文件名,因为它们引用了取自它们的样本。
谢谢
你不需要使用ls
;使用ls
的任何模式都可以用来填充数组,然后将其内容用作cat
的参数。首先将所有内容写入临时文件,以确保在覆盖第一个文件之前连接成功。
to_cat=( *_R1_* )
tmp=$(mktemp)
cat "${to_cat[@]}" > "$tmp" && mv "$tmp" "${to_cat[0]}"
您可以选择确保找到要连接的文件。(为了安全起见,我推荐它。)
shopt -s nullglob
to_cat=( *_R1_*)
tmp=$(mktemp)
(( ${#to_cat[@]} )) && cat "${to_cat[@]}" > "$tmp" && mv "$tmp" "${to_cat[0]}"
因为您想要保存文件名,所以我收集到文件名中直到最后一个下划线的所有内容都是保存的候选内容,最后三位数字是递增的块标识符。
因此,您可能希望处理大量的这些文件,而不必为每个文件修改脚本。
这个怎么样?
#!/usr/bin/env bash
# Detect a "-f" option, which forces recreation of files.
if [ "$1" = "-f" ]; then
force=true
else
force=false
fi
# First, get our list of prefixes into an array,
# stripping from the last underscore to the end of each name.
a=(*.fastq.gz)
prefixes="${a[@]%_*}"
# Next, step through the prefixes array, concatenating the chunks.
for prefix in "${prefixes[@]}"; do
if [ ! -s "${prefix}_joined.fastq.gz" ] || $force; then
cat "${prefix}"_[0-9]*.fastq.gz > "${prefix}_joined.fastq.gz"
fi
done
注意"-f"选项。我包含它的目的是,如果您在一个大的文件集合上运行此脚本,该脚本将快速跳过在前一批处理中处理过的文件。
我建议将您的文件合并到单独的文件中,而不是覆盖您的第一个文件,这样如果出现问题,您就不会损坏原始数据。毕竟,结果应该是可重复的!: -)
你必须先gunzip
试题:
gunzip -c *_R1_001.fastq.gz | gzip > result.gz