awk - 如果pattern匹配两行,如何融合两行的信息?
问题描述
我想融合两行的信息,如果第二列和第三列的坐标重叠并且第一列是相同的。
输入:
chr1 2 29 tcttttcagtgtctttagatgtgtact,
chr1 30 55 agcacatgattagaagctaccaatgg,
chr1 33 58 acatgattagaagctaccaatggccc,
chr2 30 52 ctaggcttacagaagtgagccc,
输出:
chr1 2 29 tcttttcagtgtctttagatgtgtact,
chr1 30 58 agcacatgattagaagctaccaatggccc,
chr2 30 52 ctaggcttacagaagtgagccc,
输出的第二行覆盖输入的第 2 行和第 3 行的跨度,从 30(从第 2 行开始)到 58(从第 3 行开始)(当条件为真时,坐标与第 1 列重叠是相等的)。每个坐标都链接到第 4 列的对应字母。对于输入的第二行:
30 31 32 33 34 35 36 ... 50 51 52 53 54 55
a g c a c a t ... c a a t g g
所以如果融合了坐标,那么第4列的信息也应该融合。在这种情况下,最后添加了三个字母:
30 31 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58
a g c a c a t ... c a a t g g c c c
我试图每 2 行减去第 2 列,并删除第 2 列中包含相似值的行。但我不知道如何融合信息。
awk 'NR-1{print $2-p}{p=$2}1' input.txt | paste - - | awk '($5>BiggerAs || $5<-SmallerAs)'
解决方案
OP评论中的假设和细节收集:
- 列 2/3 是开始/结束索引(分别)表示来自染色体序列的子字符串
- 第 4 列是染色体序列的实际子串
- 数据已经排序
- 目标是合并相关索引重叠的子字符串(例如,在 OP 的示例数据中,我们需要合并第 2 行和第 3 行)
- 如果重叠的子字符串在同一位置具有不同的值,则第一个值将被捕获/存储为“正确”值(即,我们不会验证重叠位置是否相同)
方法:
- 使用第 2/3 列中的值作为稀疏数组的索引,其中每个数组元素都是一个字母
- 对于重叠的子字符串,我们将那些尚未看到的位置/字母添加到数组中
使用 OP 的原始样本数据集:
$ cat input.txt
chr1 196308345 196308372 tcttttcagtgtctttagatgtgtact,
chr1 63095765 63095788 agcacatgattagaagctaccaatg
chr1 63095768 63095791 acatgattagaagctaccaatgccc,
chr2 63095768 63095789 ctaggcttacagaagtgagcc,
一种awk
解决方案:
awk '
function print_seq() # function to print the merged data
{
if ( seqend == 0 ) # make sure we have something to print; "seqend == 0" => we haven't processed any data, yet
return
printf "%-7s %-11s %-11s ", prev1, seqstart, seqend # print first 3 columns
for (i in myseq) # print merged substring
printf "%s",myseq[i]
printf ",\n" # print trailing comma + linefeed
}
function reset_ends() # function to reset our start/end indices
{
seqstart = 2^PREC
seqend = 0
}
BEGIN { reset_ends() } # (re)set our indices
# if field 1 has changed or columns 2 & 3 are outside the previously seen index range then
# print the last substring and reset some variables
prev1 != $1 ||
$2 > seqend ||
$3 < seqstart { print_seq() # print the last seq ...
reset_ends() # reset our indices ...
delete myseq # delete array containing last overlapping substring ...
prev1=$1 # reset our "previous field 1" tracker
}
# process a new, or overlapping, substring
{ seqstart = $2 < seqstart ? $2 : seqstart # new/lesser sequence start?
seqend = $3 > seqend ? $3 : seqend # new/greater sequence end?
j=$2 # initial index for myseq[] array
gsub(",","",$4) # remove commas (eg, trailing comma)
n=split($4,arr,"") # split column 4 into array of single-letter elements; "n" == number of elements in array
for (i=1; i<=n; i++) # loop through our new set of letters
if ( j in myseq ) # if we have already seen a letter for position "j" ...
j++ # increment j otherwise ...
else
myseq[j++]=arr[i] # add this new letter to our merged substring
}
END { print_seq() } # print last substring
' input.txt
以上生成:
chr1 196308345 196308372 tcttttcagtgtctttagatgtgtact,
chr1 63095765 63095791 agcacatgattagaagctaccaatgccc,
chr2 63095768 63095789 ctaggcttacagaagtgagcc,
另一种方法(对于要合并的行)将使用索引差异来仅提取新的第 4 列字符串的“未见”部分(例如,通过substring()
函数)并在之前看到的第 4 列字符串之前添加/附加。
推荐阅读
- python - 十六进制到二进制问题
- python - 使用 TextBlob 执行情感分析的缺点和潜在问题是什么?他们怎么能解决?
- r - 在 Netlify 上部署后,Blogdown 网站未显示我的图片
- php - heroku 运行 php artisan 迁移
- tortoisesvn - 结帐时检查总和错误
- javascript - 在 ComponentWillMount 函数 / setState 不起作用之前反应渲染组件
- boolean-logic - 简化xnor的正确方法是什么
- c++11 - 获取最接近双精度的 std::vector 中的值的项目
- elasticsearch - 删除索引后是否可以从 Elasticsearch 恢复数据?
- reactjs - 使用 Lab Material UI Pickers 时出现导入错误