Выборочное переформатирование файла с пробелами и \ n - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть несколько файлов в следующем формате. У этого есть 3 последовательности (число последовательностей изменяется во всех файлах, но всегда заканчиваются на ".") С 40 позициями каждый, как указано числами в первой строке. С начала строк (кроме первой) есть имена последовательностей:

3 40
00076284. ATGTCTGTGG TTCTTTAACC 
00892634. TTGTCTGAGG TTCGTAAACC 
00055673. TTGTCTGAGG TCCGTGAACC 

          GCCGGGAACA TCCGCAAAAA
          ACCGTGAAAC GGGGTGAACT
          TCCCCCGAAC TCCCTGAACG

Мне нужно преобразовать его в этот формат, где последовательности являются непрерывными, без пробелов и \ n и в новой строке после их имен. Единственные пробелы, которые должны остаться, находятся между двумя числами в первой строке.

3 40
00076284. 
ATGTCTGTGGTTCTTTAACCGCCGGGAACATCCGCAAAAA
00892634. 
TTGTCTGAGGTTCGTAAACCACCGTGAAACGGGGTGAACT
00055673. 
TTGTCTGAGGTCCGTGAACCTCCCCCGAACTCCCTGAACG

Попытка sed удалить пробелы и \ n, но не знаю, как применить его после первой строки и как избежать создания одной огромной строки.

Спасибо

Ответы [ 3 ]

1 голос
/ 28 февраля 2020

Вот сценарий оболочки, который может предоставить то, что вам нужно:

head -1 input
awk '
NR == 1 {  sequences = $1 ; positions = $2 ; next }
{ 
  if ( $1 ~ /^[0-9]/ ) {
    sid = $1 ; $1 = "" ; sequence_name[ NR - 1 ] = sid 
    sequence[ NR - 1 ] = $0
  } else {
    sequence[ ( NR - 1 )  % ( sequences + 1 ) ]  = sequence[ (NR-1) % ( sequences + 1 ) ] " " $0
  }
}
END {
  for ( x = 1 ; x <= length( sequence_name ) ; x++ )
  {
    print sequence_name[x]
    print sequence[x]
  }
}' input | tr -d ' ' 

Я добавил head -1 в верхнюю часть оболочки, чтобы получить первую строку из вашего файла. Я не смог вывести первую строку в скрипте awk из-за канала в tr -d ' '.

0 голосов
/ 28 февраля 2020

Запомните положение пустой строки и объедините строки перед пустой строкой со строками после:

awk '
   NR==1{print;next}
   NR!=1 && !empty{arr[NR]=$1 "\n" $2 $3}
   /^$/{empty=NR-1;next}
   NR!=1 && empty{printf "%s%s%s\n", arr[NR-empty], $1, $2}
' file 

Мое второе решение без awk: объединить файл с самой собой, используя пустую строку в качестве разделителя

cat >file <<EOF
3 40
00076284. ATGTCTGTGG TTCTTTAACC 
00892634. TTGTCTGAGG TTCGTAAACC 
00055673. TTGTCTGAGG TCCGTGAACC 

          GCCGGGAACA TCCGCAAAAA
          ACCGTGAAAC GGGGTGAACT
          TCCCCCGAAC TCCCTGAACG
EOF

head -n1 file
paste <(sed -n '1!{ /^$/q;p; }' file) <(sed -n '1!{ /^$/,//{/^$/!p}; }' file) |
sed 's/[[:space:]]//g; s/\./.\n/'

Будет выводить:

3 40
00076284.
ATGTCTGTGGTTCTTTAACCGCCGGGAACATCCGCAAAAA
00892634.
TTGTCTGAGGTTCGTAAACCACCGTGAAACGGGGTGAACT
00055673.
TTGTCTGAGGTCCGTGAACCTCCCCCGAACTCCCTGAACG

:

  • head -n1 file выводить первую строку
  • sed -n '1!{ /^$/q;p; }' file
    • 1! - не выводить первую строку
    • /^$/q - выходить при пустой строке
    • p печатать все остальное
  • sed -n '1!{ /^$/,//{/^$/!p}; }' file
    • 1! - игнорировать первую строку
    • /^$/,// - от пустой строки до конца
    • /^$/!p - выводить, если не пустой тлайн
  • paste <(..) <(...) - объединить два герба с вкладкой
  • sed 's/[[:space:]]//g; s/\./.\n/
    • s/[[:space:]]//g; удалить все пробелы
    • s/\./.\n/ заменить a запятая с запятой и переводом строки.
0 голосов
/ 28 февраля 2020

Я думаю, что это должно сработать, но мой вывод будет длиннее, поскольку, если я на самом деле конкатирую все последние "сиротские" последовательности, я получаю намного более длинную строку.

cat input.txt  | awk '/^[0-9]+ [0-9]+$/{printf("%s\n",$0); next} /[0-9]+[.]/{ printf("\n%s\n",$1);for(i=2; i<=NF;i++){printf("%s",$i)}; next} /^ */{ for(i=1; i<=NF;i++){printf("%s",$i)}; next;}'
3 40

Пожалуйста, попробуйте и дайте мне знать.

...