如何为我的床文件中的每个脚手架添加一列升序数字
How can I add a column of ascending numbers for each scaffold in my bed file
所以我有一个这样的文件,每一行代表脚手架中的一个位置,省略了一些位置。 (每个脚手架实际上还有很多行):
SCF_1 0 1
SCF_1 3 4
SCF_1 9 10
SCF_2 0 1
SCF_2 4 5
SCF_2 12 13
SCF_2 23 24
SCF_2 79 80
SCF_3 2 3
SCF_4 1 2
...
最终我想为每个脚手架分别制作 100kb 大小的 windows(每个脚手架上的最后一个 window 将小于 100kb)。它应该是这样的:
SCF_1 0 280000
SCF_1 280000 576300
SCF_1 576300 578000
SCF_2 9002 630000
...
范围应该不统一,因为有些位置被省略了。
我正在考虑以某种方式为每个脚手架制作另一列,其中包含升序数字,但我是编码新手,不知道如何做。
SCF_1 0 1 0
SCF_1 3 4 1
SCF_1 9 10 2
SCF_2 0 1 0
SCF_2 4 5 1
SCF_2 12 13 2
SCF_2 23 24 3
SCF_2 79 80 4
SCF_3 2 3 0
SCF_3 5 6 1
好的,我完成了一个 bash 脚本,它可以满足您的需要。继续将以下内容保存为 num_count.sh(或者任何你想要的格式,只要它是 shell 脚本格式),它应该可以为你解决问题:
#!/bin/bash
#Color declarations
RED='3[0;31m'
GREEN='3[0;32m'
LIGHTBLUE='3[1;34m'
LIGHTGREEN='3[1;32m'
NC='3[0m' # No Color
#Ignore the weird spacing. I promise it looks good when it's echoed out to the screen.
echo -e ${LIGHTBLUE}"############################################################"
echo "# Running string counting script. #"
echo "# #"
echo -e "# ${LIGHTGREEN}Syntax: num_count.sh inputFile outputFile${LIGHTBLUE} #"
echo "# #"
echo "# The script will count the number of instances of #"
echo "# the first string and increment the number as it #"
echo "# finds a new one, appending it to the end of each line. #"
echo -e "############################################################"${NC}
numCount=0
oldStr=null
if [ -z "" ] || [ -z "" ]; then
echo "Insufficient arguments. Please correct your parameters and run the script again."
exit
fi
>
while IFS= read -r line; do
firstStr=$(echo $line | awk '{print ;}')
if [ $oldStr == $firstStr ] ; then
((numCount++))
echo -e "$line\t$numCount" >>
else
oldStr=$firstStr
numCount=0
echo -e "$line\t$numCount" >>
fi
done <
基本上,您需要 运行 脚本,第一个参数作为包含您要计数的行的文件,第二个参数作为输出文件。请小心,因为输出文件将被输出数据覆盖。希望对您有所帮助!
前后对比如下:
之前:
SCF_1 0 1
SCF_1 3 4
SCF_1 9 10
SCF_2 0 1
SCF_2 4 5
SCF_2 12 13
SCF_2 23 24
SCF_2 79 80
SCF_3 2 3
SCF_4 1 2
之后:
SCF_1 0 1 0
SCF_1 3 4 1
SCF_1 9 10 2
SCF_2 0 1 0
SCF_2 4 5 1
SCF_2 12 13 2
SCF_2 23 24 3
SCF_2 79 80 4
SCF_3 2 3 0
SCF_4 1 2 0
这似乎可以很简单地使用 awk(假设您的文件名为 scf.txt
):
awk 'BEGIN {OFS = "\t"} {counts[]++; print [=10=],counts[]-1}' scf.txt
首先,我们将输出字段分隔符(OFS
)设置为列表("\t"
)。
然后,对于每一行,我们查看第一个字段 (</code>) 并在 <code>counts
table 和 print
当前行 ([=19= ]
) 后跟当前第一列值对应的计数器的值($counts[]
)减1.
以上命令输出如下:
SCF_1 0 1 0
SCF_1 3 4 1
SCF_1 9 10 2
SCF_2 0 1 0
SCF_2 4 5 1
SCF_2 12 13 2
SCF_2 23 24 3
SCF_2 79 80 4
SCF_3 2 3 0
SCF_4 1 2 0
您可以重定向到一个新文件来保存结果,而不是将其显示在终端上:
awk 'BEGIN {OFS = "\t"} {counts[]++; print [=12=],counts[]-1}' scf.txt > scf_counted.txt
(如果脚手架未分组,此解决方案也可能有效,但您似乎不需要此额外功能。)
所以我有一个这样的文件,每一行代表脚手架中的一个位置,省略了一些位置。 (每个脚手架实际上还有很多行):
SCF_1 0 1
SCF_1 3 4
SCF_1 9 10
SCF_2 0 1
SCF_2 4 5
SCF_2 12 13
SCF_2 23 24
SCF_2 79 80
SCF_3 2 3
SCF_4 1 2
...
最终我想为每个脚手架分别制作 100kb 大小的 windows(每个脚手架上的最后一个 window 将小于 100kb)。它应该是这样的:
SCF_1 0 280000
SCF_1 280000 576300
SCF_1 576300 578000
SCF_2 9002 630000
...
范围应该不统一,因为有些位置被省略了。 我正在考虑以某种方式为每个脚手架制作另一列,其中包含升序数字,但我是编码新手,不知道如何做。
SCF_1 0 1 0
SCF_1 3 4 1
SCF_1 9 10 2
SCF_2 0 1 0
SCF_2 4 5 1
SCF_2 12 13 2
SCF_2 23 24 3
SCF_2 79 80 4
SCF_3 2 3 0
SCF_3 5 6 1
好的,我完成了一个 bash 脚本,它可以满足您的需要。继续将以下内容保存为 num_count.sh(或者任何你想要的格式,只要它是 shell 脚本格式),它应该可以为你解决问题:
#!/bin/bash
#Color declarations
RED='3[0;31m'
GREEN='3[0;32m'
LIGHTBLUE='3[1;34m'
LIGHTGREEN='3[1;32m'
NC='3[0m' # No Color
#Ignore the weird spacing. I promise it looks good when it's echoed out to the screen.
echo -e ${LIGHTBLUE}"############################################################"
echo "# Running string counting script. #"
echo "# #"
echo -e "# ${LIGHTGREEN}Syntax: num_count.sh inputFile outputFile${LIGHTBLUE} #"
echo "# #"
echo "# The script will count the number of instances of #"
echo "# the first string and increment the number as it #"
echo "# finds a new one, appending it to the end of each line. #"
echo -e "############################################################"${NC}
numCount=0
oldStr=null
if [ -z "" ] || [ -z "" ]; then
echo "Insufficient arguments. Please correct your parameters and run the script again."
exit
fi
>
while IFS= read -r line; do
firstStr=$(echo $line | awk '{print ;}')
if [ $oldStr == $firstStr ] ; then
((numCount++))
echo -e "$line\t$numCount" >>
else
oldStr=$firstStr
numCount=0
echo -e "$line\t$numCount" >>
fi
done <
基本上,您需要 运行 脚本,第一个参数作为包含您要计数的行的文件,第二个参数作为输出文件。请小心,因为输出文件将被输出数据覆盖。希望对您有所帮助!
前后对比如下:
之前:
SCF_1 0 1 SCF_1 3 4 SCF_1 9 10 SCF_2 0 1 SCF_2 4 5 SCF_2 12 13 SCF_2 23 24 SCF_2 79 80 SCF_3 2 3 SCF_4 1 2
之后:
SCF_1 0 1 0 SCF_1 3 4 1 SCF_1 9 10 2 SCF_2 0 1 0 SCF_2 4 5 1 SCF_2 12 13 2 SCF_2 23 24 3 SCF_2 79 80 4 SCF_3 2 3 0 SCF_4 1 2 0
这似乎可以很简单地使用 awk(假设您的文件名为 scf.txt
):
awk 'BEGIN {OFS = "\t"} {counts[]++; print [=10=],counts[]-1}' scf.txt
首先,我们将输出字段分隔符(OFS
)设置为列表("\t"
)。
然后,对于每一行,我们查看第一个字段 (</code>) 并在 <code>counts
table 和 print
当前行 ([=19= ]
) 后跟当前第一列值对应的计数器的值($counts[]
)减1.
以上命令输出如下:
SCF_1 0 1 0
SCF_1 3 4 1
SCF_1 9 10 2
SCF_2 0 1 0
SCF_2 4 5 1
SCF_2 12 13 2
SCF_2 23 24 3
SCF_2 79 80 4
SCF_3 2 3 0
SCF_4 1 2 0
您可以重定向到一个新文件来保存结果,而不是将其显示在终端上:
awk 'BEGIN {OFS = "\t"} {counts[]++; print [=12=],counts[]-1}' scf.txt > scf_counted.txt
(如果脚手架未分组,此解决方案也可能有效,但您似乎不需要此额外功能。)