每个第i个字符打印子字符串

Sil*_*sti 5 bash awk substr

我有一些文件想以“滑动窗口”的方式分为子字符串,增量为1个字符。这些文件每个只有一行,我可以这样打印子字符串:

input="file.txt"
awk '{print substr($1,1,21)}' $input


awk '{print substr($1,2,21)}' $input
Run Code Online (Sandbox Code Playgroud)

这分别给了我以下输出。

AATAAGGTGCCTGATTAAA-G   
ATAAGGTGCCTGATTAAA-GG
Run Code Online (Sandbox Code Playgroud)

输入文件包含约17,000个字符,我设法尝试执行for循环以计算字符并在for循环内尝试上述命令,如下所示:

count=`wc -c ${input} |cut -d' ' -f1`
for num in `seq ${count}`
   do
awk '{print substr($1,$num,21)}' $input
   done
Run Code Online (Sandbox Code Playgroud)

但这将返回空输出。我还想将其作为bash脚本运行,并在命令行中指定输入和子字符串以及输出文件的大小,例如:

script.sh input_file.txt 21 output.txt
Run Code Online (Sandbox Code Playgroud)

我尝试过,但是也没有用。

  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
Run Code Online (Sandbox Code Playgroud)

关于我在做什么错的任何提示?我对awk很陌生...

Pes*_*The 3

#!/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"
Run Code Online (Sandbox Code Playgroud)

它仅使用子字符串扩展,引用手册:

${parameter:offset:length}

这称为子串扩展。它扩展到 从 指定的字符开始的length值的字符数。parameteroffset


使用gawk

awk -v num="$kmer" '{for(i=1;i<=length($0);i++) print substr($0,i,num)}' "$input" > "$output"
Run Code Online (Sandbox Code Playgroud)

这是一个更快的解决方案。速度差异显着:在 17k 个字符和 30 个字符的窗口上进行测试:第一个解决方案约为10 秒,第二个解决方案约为0.01 秒。