【问题标题】:Create a csv file based on variables in AWK根据 AWK 中的变量创建 csv 文件
【发布时间】:2022-01-29 20:12:49
【问题描述】:

这对于某些人来说看起来相对简单,但就我而言,我花了很多时间但它不起作用。我想做的是创建一个用逗号分隔的 csv 文件,使用列表中提供的 fastq_1 M1、fastq_2 M2 和变量的名称作为信息。 csv header的名字应该是sample,fastq_1,fastq_2,strandness,并且每个变量和名字必须在header的同一列中匹配。

fastq folder

S1_1.fastq.gz
S1_2.fastq.gz
S2_1.fastq.gz
S2_2.fastq.gz 
S3_1.fastq.gz
S3_2.fastq.gz
S4_1.fastq.gz
S4_2.fastq.gz

# variables
sample="mouse"
M1=$(ls *_1.fastq.gz)
M2=$(ls *_2.fastq.gz)
strandedness="paired"

#code
awk '
BEGIN      { OFS=",";
             print "sample", "fastq_1", "fastq_2", "strandedness"
           }
FNR==NR    {
             print $sample, $M1, $M2, $strandedness
           }' > output.csv

期望的输出

sample, fastq_1, fastq_2, strandedness  #header
mouse, S1_1.fastq.gz, S1_2.fastq.gz, paired #values
mouse, S2_1.fastq.gz, S2_2.fastq.gz, paired #values
mouse, S3_1.fastq.gz, S3_2.fastq.gz, paired #values
mouse, S4_1.fastq.gz, S4_2.fastq.gz, paired #values

如果有人能帮我解决这个问题,我会很高兴

【问题讨论】:

  • 请使用以下输出更新问题:typeset -p sample fastq_1 fastq_2 strandedness;虽然我假设您正在匹配文件名(来自fastq_1fastq_2),但目前尚不清楚您如何确定要匹配哪些文件...请更新问题并解释您如何确定哪些文件要匹配在一起,还提供有关如何处理无法匹配的文件的详细信息(例如,将它们添加到输出中,但“缺失”文件的空白字段?)
  • 我已经更新了。 @markp-fuso 基本上 awk BEGIN { OFS=","; print "sample", "fastq_1", "fastq_2", "strandedness"} 是 CSV 文件的标题,我想要的是 $sample 的值包含在名为 sample 的列中,以此类推
  • 您所做的只是将字符串 typeset -p 添加到您的预期输出中; not 向我们展示了变量中的内容;在填充变量之后和awk 调用之前运行typeset -p sample fastq_1 fastq_2 strandedness,然后使用typeset -p ... 调用生成的完整输出集更新问题;此外,您的最新更新将您的变量显示为一组以逗号分隔的字符串......您之前的编辑显示了数组和(未定义)字符串的混合......它是什么?解决方案/想法将根据字符串与数组而有所不同
  • @markp-fuso 我提供了新的资料,希望能容易理解
  • 您是否 100% 确定您的 fastq 文件是成对出现的(_1_2)?如果没有,如果文件没有匹配,我们应该怎么做?是基于文件名的第一部分在下划线之前的“匹配”吗?​还有其他我们需要注意的文件名格式吗?

标签: bash csv variables awk


【解决方案1】:
$ ls fastq_folder
S1_1.fastq.gz  S2_1.fastq.gz  S3_1.fastq.gz  S4_1.fastq.gz
S1_2.fastq.gz  S2_2.fastq.gz  S3_2.fastq.gz  S4_2.fastq.gz

$ cat tst.awk
BEGIN {
    OFS=","
    print "sample", "fastq_1", "fastq_2", "strandedness"
    for (i=1; i<ARGC; i++) {
        sub(".*/","",ARGV[i])
        file1 = file2 = ARGV[i]
        sub(/_1/,"_2",file2)
        print sample, file1, file2, strandedness
    }
    exit
}

$ awk -v sample="$sample" -v strandedness="$strandedness" -f tst.awk fastq_folder/*_1.fastq.gz
sample,fastq_1,fastq_2,strandedness
mouse,S1_1.fastq.gz,S1_2.fastq.gz,paired
mouse,S2_1.fastq.gz,S2_2.fastq.gz,paired
mouse,S3_1.fastq.gz,S3_2.fastq.gz,paired
mouse,S4_1.fastq.gz,S4_2.fastq.gz,paired

以上假设文件总是按照您在评论中的说明配对,并且文件数量不会超过 shell 的 ARGS_MAX。

【讨论】:

  • 正如预期的那样,使用 awk 最简单的方法是处理 ARGV; +1
【解决方案2】:

为此,纯 bash 可能比 awk 更容易:

#!/bin/bash

sample=mouse
strandedness=paired
fastq_folder=./
{
    # header
    printf '%s, %s, %s, %s\n' sample fastq_1 fastq_2 strandedness

    # values
    for fastq_1 in "$fastq_folder"/*_1.fastq.gz
    do
        fastq_2="${fastq_1%_1.fastq.gz}_2.fastq.gz"

        [[ -f $fastq_2 ]] || continue # you may display an error message

        printf '%s, %s, %s, %s\n' \
            "$sample" \
            "${fastq_1##*/}" \
            "${fastq_2##*/}" \
            "$strandedness"
    done
} > output.csv

输出.csv:

sample, fastq_1, fastq_2, strandedness
mouse, S1_1.fastq.gz, S1_2.fastq.gz, paired
mouse, S2_1.fastq.gz, S2_2.fastq.gz, paired
mouse, S3_1.fastq.gz, S3_2.fastq.gz, paired
mouse, S4_1.fastq.gz, S4_2.fastq.gz, paired

备注:在逗号后加一个空格可能看起来更漂亮,但在 CSV 术语中,这样做就是在数据中添加一个空格字符。

【讨论】:

  • 你如何重定向到像output.csv这样的文件?
  • 我用一种方法编辑了答案,但更方便的是不在脚本中硬编码它,而是在启动它时重定向输出,就像任何其他命令一样
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多