我很确定这很简单,但我没有找到与此问题相关的问题。
我正在使用下一个代码打印PosGen.bed
第5列中给定基因的第一个起始位点和最终终点位点
awk 'BEGIN{ch=$1;ini=$2;fin=$3;gen=$5}{if(gen==$5){fin=$3}else{print ch"\t"ini"\t"fin"\t"gen;ch=$1;ini=$2;fin=$3;gen=$5}}}END{print ch"\t"ini"\t"fin"\t"gen}' PosGen.bed | head
我所做的是保留第一个网站> BEGIN<。然后,条件if
将验证下一行,甚至第一行是否具有相同的基因名称,如果是,则使用新的结束站点刷新结束站点。
如果检测到其他基因名称,它将打印出所有实际信息并将其替换为新基因的信息。我的代码按预期工作,但我无法摆脱那个初始行;这可以很容易地从输出文件中删除,但我很想学习并最终掌握awk
...
所以,问题是:我的代码正在打印一个初始空行,我没有检测到原因,你知道为什么要打印一个空行吗?
我虽然这是因为错误的{braquets},但这似乎不是问题所在。 这是我得到的输出和输入的一个例子。
任何帮助都将受到高度赞赏! 谢谢!
chr1 3204563 3661429 Xkr4
chr1 4280927 4399268 Rp1
chr1 4481009 4486494 Sox17
chr1 4763279 4775758 Mrpl15
chr1 3204563 3207049 - Xkr4
chr1 3206103 3206105 - Xkr4
chr1 3206106 3207049 - Xkr4
chr1 3411783 3411982 - Xkr4
chr1 3411783 3411982 - Xkr4
chr1 3660633 3661429 - Xkr4
chr1 3660633 3661579 - Xkr4
chr1 3661427 3661429 - Xkr4
chr1 4280927 4283093 - Rp1
chr1 4283062 4283064 - Rp1
chr1 4283065 4283093 - Rp1
chr1 4333588 4340172 - Rp1
chr1 4334681 4334683 - Rp1
chr1 4334684 4340172 - Rp1
chr1 4341991 4342162 - Rp1
chr1 4341991 4342162 - Rp1
chr1 4341991 4342162 - Rp1
chr1 4341991 4342162 - Rp1
chr1 4342283 4342906 - Rp1
chr1 4342283 4342918 - Rp1
chr1 4342283 4342918 - Rp1
chr1 4342283 4342918 - Rp1
chr1 4342904 4342906 - Rp1
chr1 4350281 4350395 - Rp1
chr1 4399251 4399268 - Rp1
chr1 4399251 4399322 - Rp1
chr1 4399266 4399268 - Rp1
chr1 4481009 4482749 - Sox17
chr1 4481797 4481799 - Sox17
chr1 4481800 4482749 - Sox17
chr1 4483181 4483487 - Sox17
chr1 4483181 4483547 - Sox17
chr1 4483485 4483487 - Sox17
chr1 4483853 4483944 - Sox17
chr1 4485217 4486023 - Sox17
chr1 4486372 4486494 - Sox17
chr1 4763279 4764597 - Mrpl15
答案 0 :(得分:2)
在}
之前还有一个额外的END
会导致代码失败(出错),将其删除。
BEGIN
部分没有执行任何操作,因为$1,$2 etc
在第一行运行之前不包含任何内容。
重写一些代码,使其更容易阅读
由于gen
在首次运行时未包含任何内容,因此您if
会转到else
部分。
它首先要做的是打印ini
fin
和gen
。并且在第一次运行时,这不包含任何内容,给出空白行(错误使用BEGIN
)
awk '
BEGIN {
ch=$1
ini=$2
fin=$3
gen=$5
}
{
if (gen==$5) {
fin=$3
}
else {
print ch"\t"ini"\t"fin"\t"gen
ch=$1
ini=$2
fin=$3
gen=$5
}
}
END {
print ch"\t"ini"\t"fin"\t"gen
}
' file
PS在此处发布时,选择代码并单击{}
以概述代码。
要解决此问题,请将BEGIN
更改为NR==1
,使其像第一行一样运行:
awk -v OFS='\t' '
NR==1 {
ch=$1
ini=$2
fin=$3
gen=$5
}
{
if (gen==$5) {
fin=$3
}
else {
print ch, ini, fin, gen
ch=$1
ini=$2
fin=$3
gen=$5
}
}
END {
print ch, ini, fin, gen
}
' file
chr1 3204563 3661429 Xkr4
chr1 4280927 4399268 Rp1
chr1 4481009 4486494 Sox17
chr1 4763279 4764597 Mrpl15
答案 1 :(得分:2)
正如@Jotne指出的那样,你误解了BEGIN
的使用 - 它是在第一个输入文件被打开阅读之前执行的,因此$0
,$1
等不是填充在该部分。试试这个:
$ cat tst.awk
BEGIN{ OFS="\t" }
{
if ($5 == gen) {
fin = $3
}
else {
prtGen()
ch = $1
ini = $2
gen = $5
}
}
END { prtGen() }
function prtGen() {
if (ini != "") {
print ch, ini, fin, gen
}
}
$
$ awk -f tst.awk file
chr1 3204563 3661429 Xkr4
chr1 4280927 4399268 Rp1
chr1 4481009 4486494 Sox17
chr1 4763279 4764597 Mrpl15
请注意,如果输入文件为空,则上述操作不会产生任何输出,这是您在文本处理脚本中始终需要的内容。
答案 2 :(得分:0)
不是对起始空行问题的回答,但是在这种情况下,如果输入文件是有序的,这种替代方法可能会很有趣:
awk '$NF!=p{print x}{p=$NF}1' file | awk '{print $1,$2,$(NF-2),$NF}' RS=
输出:
chr1 3204563 3661429 Xkr4
chr1 4280927 4399268 Rp1
chr1 4481009 4486494 Sox17
chr1 4763279 4764597 Mrpl15