我有一些文件,我想以“滑动窗口”方式以 1 个字符为增量分成子字符串。每个文件只有一行,我可以像这样打印子字符串:
input="file.txt"
awk '{print substr($1,1,21)}' $input
awk '{print substr($1,2,21)}' $input
分别给我以下输出。
AATAAGGTGCCTGATTAAA-G
ATAAGGTGCCTGATTAAA-GG
输入文件包含大约 17k 个字符,我设法尝试执行一个 for 循环来计算字符数,并在 for 循环中尝试上面的命令,如下所示:
count=`wc -c ${input} |cut -d' ' -f1`
for num in `seq ${count}`
do
awk '{print substr($1,$num,21)}' $input
done
但这会返回空输出。我还想将它作为 bash 脚本运行,其中包含在命令行中指定的输入和子字符串的大小以及输出文件,例如:
script.sh input_file.txt 21 output.txt
我试过了,但还是不行。
input=$1
kmer=$2
output=$3
count=`wc -c ${input} |cut -d' ' -f1`
for num in `seq ${count}`
do
awk '{print substr($1,$num,$kmer)}' $input > $output
done
关于我做错了什么的任何提示?我是 awk 的新手...
最佳答案
#!/usr/bin/env bash
input=$1
kmer=$2
output=$3
data=$(<"$input")
for ((i=0;i<${#data};i++)); do
echo "${data:i:kmer}"
done > "$output"
它只使用substring expansion ,引自手册:
${parameter:offset:length}
This is referred to as Substring Expansion. It expands to up to
length
characters of the value ofparameter
starting at the character specified byoffset
.
使用 gawk
:
awk -v num="$kmer" '{for(i=1;i<=length($0);i++) print substr($0,i,num)}' "$input" > "$output"
这是一个大大更快的解决方案。速度差异显着:在 17k 个字符和 30 个字符的窗口上进行测试:第一个解决方案为 ~10s,第二个解决方案为 ~0.01s。
关于bash - 每第 i 个字符打印子串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51050077/