unix:获取文件中的第10到80个字符

unix:获取文件中的第10到80个字符

我有一个包含行分隔文本的文件:

GCAACACGGTGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCCTAGTCCATCAGCAAATGCCGTTTCCAGCAATGCAAAGAGAACGGGAAGGTATCAGTTCACCG
GTGACTGCCATTACTGTGGACAAAAAGGGCACATGAAGAGAGACTGTGACAAGCTAAAGGCAGATGTAGC

由此,我想提取字符 10 到 80,所以:

TGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCCT

我已经找到了如何计算文件中的字符:

  wc -m file

以及如何获取每行的字符数:

 awk '{print substr($0,2,6)}' file

但我找不到办法让字符从 10 到 80。

换行符不算作字符。

有任何想法吗?

是的,这是来自完整基因组的 DNA。我使用以下方法从包含不同支架(本例中为 10 和 11)的 fasta 文件中提取了这段 DNA

 awk '/scaffold_10\>/{p=1;next} /scaffold_11/{p=0;exit} p'

最终,我想要一个简单的命令来从指定的脚手架获取 100 到 800 个字符(或类似的字符)。

编辑:问题在这里继续:使用 gff2fasta 代替 bash 脚本从完整基因组中获取部分 DNA 序列

答案1

$ cat file1
GCAACACGGTGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCCTAGTCCATCAGCAAATGCCGTTTCCAGCAATGCAAAGAGAACGGGAAGGTATCAGTTCACCG
GTGACTGCCATTACTGTGGACAAAAAGGGCACATGAAGAGAGACTGTGACAAGCTAAAGGCAGATGTAGC

检查每行的长度

$ awk '{print length,$0}' file1
70 GCAACACGGTGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
70 GTCGAGCCTAGTCCATCAGCAAATGCCGTTTCCAGCAATGCAAAGAGAACGGGAAGGTATCAGTTCACCG
70 GTGACTGCCATTACTGTGGACAAAAAGGGCACATGAAGAGAGACTGTGACAAGCTAAAGGCAGATGTAGC

打印10-80个字符

$ awk '{print substr($0,10,70)}' RS= file1
TGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG
GTCGAGCC

假设输入不包含空行(RS=启用段落模式其中每条记录都是一个段落(段落由空行序列分隔)),这意味着将整个文件加载到内存中。

答案2

我想知道应该如何处理文件中的换行符。这算不算一个角色?

如果我们只是从字节 10 中取出并打印 71 个字节(A、C、T、G 和换行符),那么 Sato Katsura 解决方案是最快的(这里假设 GNUdd或兼容status=none, 替换为2> /dev/null(尽管这也会隐藏错误消息,如果有的话) )与其他实现):

 dd if=file bs=1 count=71 skip=9 status=none

如果应跳过换行,则使用以下命令将其过滤掉tr -d '\n'

 tr -d '\n' < file | dd bs=1 count=70 skip=9 status=none

如果应跳过 Fasta 标头,则为:

 grep -v '^[;>]' file | tr -d '\n' | dd bs=1 count=70 skip=9 status=none

grep -v '^[;>]' file;表示跳过所有以或开头的行>

答案3

对于字节(因此也适用于示例中的单字节字符):

dd bs=1 skip=9 count=71 < file 2> /dev/null

或者使用 GNU 更有效dd

dd iflag=fullblock,skip_bytes,count_bytes skip=9 count=71 status=none < file

对于字符,带有zsh

{
  IFS= read -ru0 -k9 discard &&
    IFS= read -ru0 -k71 text &&
    printf %s $text
} < file

(如果文件中的字符少于 80 个,则不会打印任何内容)。

ksh93并且bash有一个-N类似于zshs 的选项-k,但它们不支持 NUL 字符并且一个bash是越野车

使用 GNU awk

awk -v RS='.{1}' -v ORS= 'NR>=10 {print RT}; NR == 80 {exit}'

我们使用的单个字符不会被视为正则表达式.{1}.

另一种选择是转换为每个字符具有固定字节数(并且具有所有可能的字符)的字符编码,例如每个字符具有 4 个字节的 UTF-32LE:

< file iconv -t UTF-32LE |
   dd bs=4 skip=9 count=71 2> /dev/null |
   iconv -f UTF-32LE

答案4

perl -l -0777pe '
   my($start, $stop) = qw/10 80/; $delta = $stop - $start--;
   (undef, $_, $a) = unpack "A${start}A${delta}A*";
   $_ .= $1 while length() - y/\n/\n/ < $delta and $a =~ /(.)/g;
'  scaffolded_file_10

相关内容