文件由awk或grep处理

时间:2018-03-27 15:46:35

标签: awk grep

我必须处理一个大输入文件(2.9 GB)以产生特定格式的输出(如下所述:)

输入文件示例为:

GS  RSPH14
CC  Build HSA_Jul2014 (GRCh38; hg38): chr22:23141092..23152092 (REVERSE)
FT  TFBS CHIP: FR000000873; SP1 (Jurkat); PMID:14980218; 23144712..23145380
FT  TFBS CHIP: FR000643682; ER-ALPHA (MCF-7); PMID:19339991; 23147445..23148194
FT  TFBS CHIP: FR029934262; C/EBPBETA (A-549); https://www.encodeproject.org/experiments/ENCSR000DYI/; 23150853..23151108
GS  CLXC15
CC  Build HSA_Jul2014 (GRCh38; hg38): chr3:23144021..23155021 (REVERSE)
FT  TFBS CHIP: FR000643682; ER-ALPHA (MCF-7); PMID:19339991; 23147445..23148194
FT  TFBS CHIP: FR034213319; CTCF (MCF-7); https://www.encodeproject.org/experiments/ENCSR000DMV/; 23151393..23151582

描述:输入文件中的每一行都以GSCCFT开头,我想忽略GS *行。对于CC *行,我想将其拆分为:并取1st index(基于0的计数),根据我的输入样本,它将为chr22(在第2行)和chr3(第7行)。对于FT行,我想将其拆分为;并取1stlast index(根据我的输入示例'第3行,它将是SP1 (Jurkat)23144712..23145380,分别)并希望以这样的方式处理它们,使我的输出文件看起来像这样:

chr22   23144712    23145380    SP1
chr22   23147445    23148194    ER-ALPHA
chr22   23150853    23151108    C/EBPBETA
chr3    23147445    23148194    ER-ALPHA
chr3    23151393    23151582    CTCF

非常感谢任何帮助!

我的尝试:我可以在;上拆分文件,以便获得所需的列。我尝试的是:awk -F'[;]' '{print $2 "\t" $4}' sample.txt > output.txt。这给了我输出:

 hg38): chr22:23141092..23152092 (REVERSE)  
 SP1 (Jurkat)    23144712..23145380
 ER-ALPHA (MCF-7)    23147445..23148194
 C/EBPBETA (A-549)   23150853..23151108

 hg38): chr3:23144021..23155021 (REVERSE)   
 ER-ALPHA (MCF-7)    23147445..23148194
 CTCF (MCF-7)    23151393..23151582

现在从第1行和第6行我只想chr22chr3以及其他行(非第1和第6行,最初以GSCC开头)只有最后一列并在前面附加相应的chr。另外,第一个其他行的索引应该被处理为在(上拆分并保留第一个索引。

3 个答案:

答案 0 :(得分:1)

使用awk:

awk '
    $1 == "CC" { split($0, a, /:/); key=a[2] }
    $1 == "FT" {
        n = split($0, a, /;/)
        split(a[2], b, FS)
        split(a[n], c, /[.]{2}/)
        print key, c[1],c[2], b[1]
    }
' file | column -t
chr22  23144712  23145380  SP1
chr22  23147445  23148194  ER-ALPHA
chr22  23150853  23151108  C/EBPBETA
chr3   23147445  23148194  ER-ALPHA
chr3   23151393  23151582  CTCF

答案 1 :(得分:1)

关注awk可能对您有帮助。

awk '/^CC.*/{match($0,/chr[0-9]+/);val=substr($0,RSTART,RLENGTH);next} /^FT.*/{sub(/\.+/,OFS,$NF);print val,$NF,$5}' OFS="\t"  Input_file

现在也添加非单线形式的解决方案。

awk '
/^CC.*/{
  match($0,/chr[0-9]+/);
  val=substr($0,RSTART,RLENGTH);
  next}
/^FT.*/{
  sub(/\.+/,OFS,$NF);
  print val,$NF,$5}
' OFS="\t"  Input_file

答案 2 :(得分:1)

根据您的要求;使用 awk

$ awk '/^CC /{FS=":"; $0=$0; a=$2} /^FT /{FS="[ ;.]+"; $0=$0;print a,$(NF-1),$NF,$5}' file
 chr22 23144712 23145380 SP1
 chr22 23147445 23148194 ER-ALPHA
 chr22 23150853 23151108 C/EBPBETA
 chr3 23147445 23148194 ER-ALPHA
 chr3 23151393 23151582 CTCF

/^CC /{FS=":"; $0=$0; a=$2;}:如果记录以CC开头(请注意空格)将:设为FS。
$0=$0将强制awk根据FS的内容拆分记录。将a设置为第二个字段

/^FT /{FS="[ ;.]+"; $0=$0; print a,$(NF-1),$NF,$5}:如果记录以FT开头(请再次注意空格)将[ ;.]+设置为FS,这会将FS等同于重复例如,或;...和你上一个字段一样。 最后,打印必填字段。