Intereting Posts
Объяснения сценария построения образа Android Как перенаправить исходящий трафик на другой ip с помощью iptables Заказ между `nohup`,` & `и перенаправление? / usr / bin / env: zsh -: нет такого файла или каталога Как я могу условно передать подоболочку через «время»? DPMS не работает: монитор не выключен Nginx требует перезагрузки после перезагрузки В xinput появляется странное устройство Скрипт XRandR корректно работает из командной строки, не работает в качестве задания cron Как настроить систему Arch Linux для автоматического монтирования внешнего жесткого диска, когда он подключен? Как создать темы для MATE? Как отключить компьютер от SLiM при отключенном корневом входе? Как переназначить мой ключ CapsLock для работы, как если бы это был ключ Return с помощью setxkbmap? Можно ли изменить файл yml с помощью сценария оболочки? Резервное копирование с использованием rsync

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, чтобы получить части ДНК-последовательностей из полного генома

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

Если мы просто должны взять из байта 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; }