unix: получить символы от 10 до 80 в файле

У меня есть файл, содержащий текст, разделенный линией:

GCAACACGGTGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG GTCGAGCCTAGTCCATCAGCAAATGCCGTTTCCAGCAATGCAAAGAGAACGGGAAGGTATCAGTTCACCG GTGACTGCCATTACTGTGGACAAAAAGGGCACATGAAGAGAGACTGTGACAAGCTAAAGGCAGATGTAGC 

Из этого я хочу извлечь символы от 10 до 80, так что:

 TGGGAGCACGTCAACAAGGAGTAATTCTTCAAGACCGTTCCAAAAACAGCATGCAAGAGCG GTCGAGCCT 

Я нашел, как считать символы в файле:

  wc -m file 

и как получить количество символов в строке:

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

но я не могу найти способ получить символы от 10 до 80.

Новые строки не считаются символами.

Есть идеи?

Да, это ДНК, из полного генома. Я извлек этот бит ДНК из файла fasta, содержащего различные леса (в этом случае 10 и 11), используя

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

В конечном счете, я хотел бы иметь простую команду, чтобы получить символы от 100 до 800 (или что-то в этом роде) от указанного эшафота.

EDIT: Вопрос продолжается здесь: используйте gff2fasta вместо сценария bash, чтобы получить части ДНК-последовательностей из полного генома

  • sed count lines между шаблоном - несколько файлов
  • Как найти файлы с длинной первой строкой?
  • получать размер файла и количество строк одновременно
  • Выберите файл на основе количества строк и обработайте результат
  • grep с количеством отдельных паттернов
  • Как считать события фразы в grep, игнорируя случай?
  • Время, необходимое для вывода трубы на голову / хвост
  • Подсчитайте строки, соответствующие шаблону и соответствующие предыдущей строке
  • 6 Solutions collect form web for “unix: получить символы от 10 до 80 в файле”

    Интересно, как обрабатывать линию в файле. Это считается персонажем или нет?

    Если мы просто должны взять из байта 10 и напечатать 71 байт (A, C, T, G и linefeed), то решение Sato Katsura является самым быстрым (здесь предполагается GNU dd или совместим для 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 означает пропустить все строки, которые начинаются с ; или > .

     $ 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= разрешает режим абзаца, где каждая запись является абзацем (абзацы разделены последовательностями пустых строк)), и это подразумевает загрузку всего файла в память.

    Для байтов (так же будет работать и для однобайтовых символов, как в вашем примере):

     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 аналогичный zsh -k , но они не поддерживают символы NUL, а bash – глючит .

    С GNU awk :

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

    Мы используем .{1} as . будучи единственным символом, не будет рассматриваться как регулярное выражение.

    Другим вариантом является преобразование в кодировку символов, которая имеет фиксированное количество байтов на символ (и имеет все возможные символы), такие как UTF-32LE, который имеет 4 байта на символ:

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

    Если вы не возражаете, чтобы все содержимое было записано в память, а с развернутой линией, вы можете использовать подстановку команд, чтобы прочитать ее (спасибо Джорджу Василиу за улучшение!)

     data=$( tr -d '\n' < inputfile ) 

    затем распечатать с (на основе нуля) 10, для длины 70 байтов:

     printf "%s\n" "${data:9:70}" 
     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 

    Предполагая, что символы новой строки не значимы для данных, а просто форматирование в файле (код не проверен):

     BEGIN { linesize=70; start=10; end=80; } // { if ((NR>=int(start/linesize) && (NR<=int(end/linesize)) { from = NR==int(start/linesize) ? start % linesize : 0; to = NR==int(end/linesize) ? (end % linesize)-from : linesize+1; print substr($0, from, to); } if (NR==int(end/linesize)) exit; } 
    Linux и Unix - лучшая ОС в мире.