使用变量名作为cat的输出

  • 本文关键字:cat 输出 变量名 bash
  • 更新时间 :
  • 英文 :


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

最新更新