通过awk或grep处理文件
我必须处理一个大的输入文件(2.9 GB),以生成特定格式的输出(如下所述:) 输入文件的示例为:通过awk或grep处理文件,awk,grep,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 (MC
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*行,我想在:
上拆分它,并获取第一个索引(基于0的计数),根据我的输入样本,它将是chr22
(在第2行)和chr3
(在第7行)。对于FT行,我想在上拆分它
并获取第一个
和最后一个索引
(根据我的输入示例的第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。另外,应处理其他行的第一个索引,以便在上拆分(
并保留第一个索引。使用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
下面的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
根据您的要求;使用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;打印一个,$(NF-1),$NF,$5}
:如果记录以FT
开头(再次注意空格),请将[;]+
设置为FS
,这将等同于重复的
或;
或例如。
。
。
最后,打印所需的字段。堆栈溢出不是免费的编码服务。您尝试了什么,它是如何失败的?这是我达到的程度:awk-F'[;]'{print$2'\t'$4}'sample.txt>output.txt
,但我无法按照我的要求进一步拆分这些索引!请您的问题解释这些内容,最好是更详细一些(您到底被困在哪里?)@tripleee你现在能帮我吗?非常感谢你抽出时间回答。它工作得非常好。如果你能在代码行中添加简短的注释,这样我就可以更好地理解解决方案,并在将来根据我的需要修改它。我不明白FS
在split(a[2],b,FS)中做了什么
请解释这一行的拆分(a[n],c,/[.]{2}/)
谢谢!FS
是常规的字段分隔符;因此该行首先拆分为分号,然后其中一个字段依次拆分为空格。[.]{2}
匹配两个相邻的文字点。在这种情况下,FS的内容已经是split的默认分隔符,因此这也会起作用:split(a[2],b)
GNU awk手册和split()
函数非常感谢您抽出时间回答。我选择了另一个答案,因为它是第一个发布的,我尝试了,它首先起作用。不过,如果您可以在代码中添加简短的注释,这样我就可以理解正在发生的事,这样我就可以根据将来的需要修改它。再次感谢在里面
$ 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