我必须处理一个大输入文件(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
描述:输入文件中的每一行都以GS
或CC
或FT
开头,我想忽略GS *行。对于CC *行,我想将其拆分为:
并取1st index
(基于0的计数),根据我的输入样本,它将为chr22
(在第2行)和chr3
(第7行)。对于FT行,我想将其拆分为;
并取1st
和last 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行我只想chr22
和chr3
以及其他行(非第1和第6行,最初以GS
或CC
开头)只有最后一列并在前面附加相应的chr。另外,第一个其他行的索引应该被处理为在(
上拆分并保留第一个索引。
答案 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
等同于重复例如,或
;
或.
。 ..
和你上一个字段一样。
最后,打印必填字段。