извлечь определенную строку, выполнить поиск и замену или сохранить более длинную строку, содержащую извлеченное значение

извлечь определенную строку, выполнить поиск и замену или сохранить более длинную строку, содержащую извлеченное значение

Входной файл, который необходимо отредактировать, выглядит следующим образом (может содержать больше строк):

bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1   intron_FBgn0035847:4_FBgn0035847:3  61  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
2   intron_FBgn0032515:2_FBgn0032515:4  72  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
3   intron_FBgn0266486:5_FBgn0266486:4  58  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
4   intron_FBgn0031359:10_FBgn0031359:7 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
4   intron_FBgn0031359:10_FBgn0031359:8 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
4   intron_FBgn0031359:10_FBgn0031359:9 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
536 intron_CR31143:1_CR31143:2  40  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00

Для каждого идентификатора во 2-м столбцеинтрон_XXXXXXXXX:X_XXXXXXXXX:X, я хочу извлечь строку междуинтрон_и 1-й:(между строкой обычно, но не всегда, начинается с FBgn).

Затем у меня есть следующий список (один столбец дляФБгна другой столбец для соответствующего имени, в которое я хочу преобразовать FBgn):

## FlyBase Gene Mapping Table   
## Generated: Fri Dec 20 12:37:29 2013  
## Using datasource: dbi:Pg:dbname=fb_2014_01_reporting;host=flysql9;port=5432...   
FBgn0035847 mthl7
FBgn0032515 loqs
FBgn0266486 CG45085
FBgn0031359 CG18317

Затем я хочу выполнить поиск извлеченной строки в первом столбце списка.

Если извлеченная строка имеет соответствующее значение во 2-м столбце, я хочу заменить весь идентификаторинтрон_FBgnXXXXXX:X_FBgnXXXXXX:Xс соответствующим именем во 2-м столбце.

Если извлеченная строка не существует в первом столбце, я хочу заменить весь идентификаторинтрон_XXXXXXXXX:X_XXXXXXXXX:Xс извлеченной строкой.

У меня есть следующий сценарий:

ref="gene_map_table_fb_2014_01_short.tsv"
target="HC25_LNv_ZT02_intron_results.txt"
output="temptemp.txt"

declare -A map
while read line
do
if [[ ! -z "$line" ]] && [[ ! "$line" =~ ^#.* ]]
then
key=$(echo "$line" | cut -f 1)
value=$(echo "$line" | cut -f 2)
map[$key]=$value
fi
done < $ref

while read line
do
  key=$(echo "$line" | sed -n 's/.*_\([^\.]*\)\:.*/\1/p' | head -1)
if [ ! -z "$key" ]
then
  echo "$line" | sed 's/intron_[^[:space:]]*/'${map[$key]}'/g' >> $output
else
  echo "$line" | sed 's/intron_[^[:space:]]*/'$key'/g' >> $output
fi
done < $target

Вроде бы все работает нормально, за исключением того, что в выходном файле отсутствуют строки, идентификаторы которых не начинаются с FBgn.

решение1

Ты можешь это сделать:

cat gene_map_table_fb_2014_01_short.tsv  |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g

Сначала cat ваш файл, затем удалите первую строку (заголовок столбцов с d1), затем выведите все столбцы, затем разделите 4_FBgn0035847с помощью awk 'BEGIN{FS=":"} {print $2}'Затем удалите number_с помощьюsed s/._//g

Выходные данные:

FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
CR31143

Однако, если у вас лишняя конечная линия и вы хотите ее удалить, вы можете сделать это:

cat gene_map_table_fb_2014_01_short.tsv  |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g |sed '$d'

Итак, вывод:

FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359

решение2

С использованиемawk

Это создает вывод, разделенный табуляцией:

$ awk -v OFS="\t" 'NR==FNR{a[$1]=$2;next} FNR==1{print;next} {sub(/intron_/, "", $2); sub(/:.*/,"",$2);if ($2 in a) $2=a[$2];print}' gene_map_table_fb_2014_01_short.tsv HC25_LNv_ZT02_intron_results.txt
bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1       mthl7   61      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
2       loqs    72      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
3       CG45085 58      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
536     CR31143 40      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00

Объяснение:

  • -v OFS="\t"

    Это превращает разделитель выходных полей в табуляцию.

  • NR==FNR{a[$1]=$2;next}

    Это создает ассоциативный массив, aоснованный на первом файле в командной строке, с первым столбцом в качестве ключа и вторым столбцом в качестве значения. Команда nextуказывает awkпропустить остальные команды и перейти к следующей строке.

    Файл отображения содержит несколько строк комментариев. Мы могли бы легко добавить дополнительный ifоператор, чтобы предотвратить их добавление в массив a. Однако, поскольку они не наносят вреда, мы пропустили это усложнение.

  • FNR==1{print;next}

    Это выведет строку заголовка без изменений.

  • {sub(/intron_/, "", $2); sub(/:.*/,"",$2)

    Это удалит лишние данные из второго поля, оставив только нужную нам строку.

  • `если ($2 в а) $2=а[$2]

    Если строка из второго поля присутствует в качестве ключа в массиве a, то мы подставляем ее соответствующее значение.

  • print

    Исправленная строка печатается.

С использованиемbash

В скрипте замените

if [ ! -z "$key" ]

С:

if [[ "$key" && "${map[$key]}" ]]

Похоже, что скрипту на данном этапе нужно знать, keyприсутствует ли в mapили нет. Пересмотренный тест гарантирует не только то, что keyэто непустое, но и то, что это в map.

Сделав это одно изменение, я получаю результат:

$ cat temptemp.txt 
bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1       mthl7   61      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
2       loqs    72      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
3       CG45085 58      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
536     CR31143 40      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00

В качестве отступления от text, [ ! -z "$key" ]возвращает true, если keyнепустое. Это эквивалентно [ -n "$key" ]. Поскольку это такой распространенный тест, его можно сократить до [ "$key" ]. Это можно использовать для упрощения нескольких строк в bashскрипте.

Связанный контент