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

标签 bash awk substr

我有一些文件,我想以“滑动窗口”方式以 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 of parameter starting at the character specified by offset.


使用 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/

相关文章:

linux - 使用 shell 遍历文件

linux - 如何替换 bash 脚本中的 'bc' 工具?

sed - 在纯文本文件的每 4 行后插入一个逗号

javascript - 检查字符串是否以给定的目标字符串结尾 | javascript

javascript - 从索引位置向后查找字符串中的空格

php - 如何创建 "if"语句来评估 PHP 中的前 7 个字符?

linux - 如何将时间附加到命令输出?

linux - 使用 shell 脚本杀死 vim 进程会留下 .swp 文件

c - 如何将行号转换为字节偏移量?

python - 使用 bash 或 python 或其他一些 linux 命令行工具创建一个 dovecot SHA1 摘要