bash: восстановление информации в строке - PullRequest
1 голос
/ 04 июня 2019

из файла, созданного с помощью предыдущего скрипта, я хочу получить мою информацию определенным способом. Действительно, я хотел бы получить информацию о rsID (уникальном), имени гена (уникальном) и списке транскрибированных имен в строке.

здесь часть моего файла rsID.txt:

rsID
rs142849724
rs141989890

здесь часть моего rsID_out.txt:

"1","rs142849724","ENSG00000228794","ENST00000624927"
"2","rs142849724","ENSG00000228794","ENST00000623808"
"3","rs142849724","ENSG00000228794","ENST00000445118"
"4","rs142849724","ENSG00000228794","ENST00000448975"
"5","rs142849724","ENSG00000228794","ENST00000610067"
"6","rs142849724","ENSG00000228794","ENST00000608189"
"7","rs142849724","ENSG00000228794","ENST00000609139"
"8","rs142849724","ENSG00000228794","ENST00000449005"
"9","rs142849724","ENSG00000228794","ENST00000416570"
"10","rs142849724","ENSG00000228794","ENST00000623070"
"11","rs142849724","ENSG00000228794","ENST00000609009"
"12","rs142849724","ENSG00000228794","ENST00000622921"
"13","rs141989890","ENSG00000228794","ENST00000624927"
"14","rs141989890","ENSG00000228794","ENST00000623808"
"15","rs141989890","ENSG00000228794","ENST00000445118"
"16","rs141989890","ENSG00000228794","ENST00000448975"
"17","rs141989890","ENSG00000228794","ENST00000610067"
"18","rs141989890","ENSG00000228794","ENST00000608189"
"19","rs141989890","ENSG00000228794","ENST00000609139"
"20","rs141989890","ENSG00000228794","ENST00000449005"
"21","rs141989890","ENSG00000228794","ENST00000416570"
"22","rs141989890","ENSG00000228794","ENST00000623070"
"23","rs141989890","ENSG00000228794","ENST00000609009"
"24","rs141989890","ENSG00000228794","ENST00000622921"

Я создал этот код:

while read line
do
    res=`grep "$line" rsID_out.txt | awk -F ',' '!seen[$3]++ {print $3 ";"}'`
    ra=`grep "$line" rsID_out.txt | awk -F ',' '{print $4}'`
    echo "$line ; $res ; $ra"
done < rsID.txt

Я получаю этот файл как результат:

rs142849724 ; "ENSG00000228794" ; "ENST00000624927"
"ENST00000623808"
"ENST00000445118"
"ENST00000448975"
"ENST00000610067"
"ENST00000608189"
"ENST00000609139"
"ENST00000449005"
"ENST00000416570"
"ENST00000623070"
"ENST00000609009"
"ENST00000622921"

rs141989890 ; "ENSG00000228794" ; "ENST00000624927"
"ENST00000623808"
"ENST00000445118"
"ENST00000448975"
"ENST00000610067"
"ENST00000608189"
"ENST00000609139"
"ENST00000449005"
"ENST00000416570"
"ENST00000623070"
"ENST00000609009"
"ENST00000622921"

Но я бы хотел получить файл в форме:

rs142849724;"ENSG00000228794";"ENST00000624927"|"ENST00000623808"|"ENST00000445118"|"ENST00000448975"|"ENST00000610067"|"ENST00000608189"|"ENST00000609139"|"ENST00000449005"|"ENST00000416570"|"ENST00000623070"|"ENST00000609009"|"ENST00000622921"

rs141989890;"ENSG00000228794";"ENST00000624927"|"ENST00000623808"|"ENST00000445118"|"ENST00000448975"|"ENST00000610067"|"ENST00000608189"|"ENST00000609139"|"ENST00000449005"|"ENST00000416570"|"ENST00000623070"|"ENST00000609009"|"ENST00000622921"

как это сделать?

Спасибо

edit: Я думаю, что наконец понял, как форматировать свой пост. Спасибо! Спасибо! В самом деле, я хочу реорганизовать rsID_out.txt в одну строку на идентификатор rs. Извините, если у вас возникли проблемы с неправильным форматированием моего поста. Файл rsID.txt содержит первую строку rsID, но не содержит пустых строк. Я принимаю к сведению ваши ответы, замечания и предложения и смотрю ваши ответы.

Ответы [ 3 ]

1 голос
/ 04 июня 2019

Предполагается, что два файла данных:

  • rsID.txt , содержащий желаемый rsID для поиска:
rs142849724
rs141989890
  • rsID_out.txt , содержащий:
"1","rs142849724","ENSG00000228794","ENST00000624927" 
"2","rs142849724","ENSG00000228794","ENST00000623808" 
"3","rs142849724","ENSG00000228794","ENST00000445118" 
"4","rs142849724","ENSG00000228794","ENST00000448975" 
"5","rs142849724","ENSG00000228794","ENST00000610067" 
"6","rs142849724","ENSG00000228794","ENST00000608189" 
"7","rs142849724","ENSG00000228794","ENST00000609139" 
"8","rs142849724","ENSG00000228794","ENST00000449005" 
"9","rs142849724","ENSG00000228794","ENST00000416570" 
"10","rs142849724","ENSG00000228794","ENST00000623070" 
"11","rs142849724","ENSG00000228794","ENST00000609009" 
"12","rs142849724","ENSG00000228794","ENST00000622921" 
"13","rs141989890","ENSG00000228794","ENST00000624927" 
"14","rs141989890","ENSG00000228794","ENST00000623808" 
"15","rs141989890","ENSG00000228794","ENST00000445118" 
"16","rs141989890","ENSG00000228794","ENST00000448975" 
"17","rs141989890","ENSG00000228794","ENST00000610067" 
"18","rs141989890","ENSG00000228794","ENST00000608189" 
"19","rs141989890","ENSG00000228794","ENST00000609139" 
"20","rs141989890","ENSG00000228794","ENST00000449005" 
"21","rs141989890","ENSG00000228794","ENST00000416570" 
"22","rs141989890","ENSG00000228794","ENST00000623070" 
"23","rs141989890","ENSG00000228794","ENST00000609009"
"24","rs141989890","ENSG00000228794","ENST00000622921"

, затем для получения запрошенного вывода с помощью awk:

awk -F, '
    NR==FNR {
        x[$1]++
        next
    }
    {
        gsub(/"/, "", $2)
        k = $2 ";" $3
    }
    $2 in x { a[k] = a[k] "|" $4 }
    END {
        for (k in a) {
            sub(/[|]/, "", a[k])
            print k ";" a[k]
        }
    }
' rsID.txt rsID_out.txt
  • NR==FNR {...} - прочитать списокrsID для поиска
  • gsub - убрать двойные кавычки
  • k - ключ (rsID; "имя гена")?
  • $2 in x - толькоrsID процесса в списке
  • END - удалить первый канал, затем напечатать каждый ключ со значением

Примечание: Этот код предполагает, что строки не должны бытьсгруппированы и могут появляться в любом порядке.Объем памяти, используемой awk, будет приблизительно пропорционален размеру rsID_out.txt, что может быть проблематично, если этот файл огромен.Альтернативные решения awk, например, Dudi Boy и Ed Morton, предполагают, что строки сгруппированы (разумное предположение на основе предоставленных выборочных данных).Это позволяет им только крошечный объем памяти.


Как предлагается в комментариях, вы также можете изменить свой код, используя sed.Примерно так:

while read line; do
    res=$( grep "$line" rsID_out.txt | awk -F , '!seen[$3]++ {print $3}' )
    ra=$( grep "$line" rsID_out.txt | awk -F , '{printf "|%s", $4} END {print ""}' | sed 's/[|]//' )
    echo "$line;$res;$ra"
done < rsID.txt

Это будет несколько менее эффективно: для каждой строки ввода grep и awk вызываются два раза и sed один раз, а не один единственный вызов awk в целом.Для больших объемов данных это может иметь значение.

0 голосов
/ 04 июня 2019

Я предлагаю один awk скрипт для запуска на rsID_out.txt, который выдаст необходимые отформатированные данные.

script.awk

!seen[$2""$3] {         # if new sequence of input lines
    seen[$2""$3] = 1;   # mark the new sequence
    if (rowCount++) print row; # if not first output row, print previous output row
    gsub("\"","",$2);   # clear redundant quote marks from 2nd field in input line
    row = $2";"$3";"$4; # assign 2nd and 3rd fields from input line, to new output row
    next;               # proceed to next input line
}
{ row = row"|"$4;}      # add 4th field from input line to output row
END { print row; }      # print the last output row.

запуск скрипта:

 awk -F "," -f script.awk rsID_out.txt

выход:

rs142849724;"ENSG00000228794";"ENST00000624927"|"ENST00000623808"|"ENST00000445118"|"ENST00000448975"|"ENST00000610067"|"ENST00000608189"|"ENST00000609139"|"ENST00000449005"|"ENST00000416570"|"ENST00000623070"|"ENST00000609009"|"ENST00000622921"
rs141989890;"ENSG00000228794";"ENST00000624927"|"ENST00000623808"|"ENST00000445118"|"ENST00000448975"|"ENST00000610067"|"ENST00000608189"|"ENST00000609139"|"ENST00000449005"|"ENST00000416570"|"ENST00000623070"|"ENST00000609009"|"ENST00000622921"

Пожалуйста, оставляйте комментарии о формате и логике вывода.

Обратите внимание, что разделитель 1-го поля и 2-го поля равен ;, а разделитель 3-го поля по отношению к последнему полю - |

0 голосов
/ 04 июня 2019

Звучит так: может быть всем, что вам нужно:

$ cat file
"1","rs142849724","ENSG00000228794","ENST00000624927"
"2","rs142849724","ENSG00000228794","ENST00000623808"
"3","rs142849724","ENSG00000228794","ENST00000445118"
"13","rs141989890","ENSG00000228794","ENST00000624927"
"14","rs141989890","ENSG00000228794","ENST00000623808"
"15","rs141989890","ENSG00000228794","ENST00000445118"

$ cat tst.awk
BEGIN { FS=","; OFS="|" }
$2 != prev {
    if ( NR > 1 ) {
        print rec
    }
    prev = $2
    gsub(/"/,"",$2)
    rec = $2 ";" $3 ";" $4
    next
}
{ rec = rec OFS $4 }
END { print rec }

$ awk -f tst.awk file
rs142849724;"ENSG00000228794";"ENST00000624927"|"ENST00000623808"|"ENST00000445118"
rs141989890;"ENSG00000228794";"ENST00000624927"|"ENST00000623808"|"ENST00000445118"

если это не все, что вам нужно, обновите свой вопрос, чтобы уточнить ваши требования и предоставить более по-настоящему репрезентативный пример ввода / вывода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...