Замените строки в файле другой совпадающей строкой из другого файла

У меня есть file1, в котором второй последний столбец является кодом для первого столбца, например, Rv0002 имеет два кода S и L:

Rv0001 - hypothetical protein Rv0019c T Signal_transduction_mechanisms Rv0002 - hypothetical protein Rv0030 S Function_unknown Rv0002 pknA TRANSMEMBRANE SERINE (STPK A) L recombination_and_repair

Существует еще один file2 который имеет все уникальные Rv0002 в первом столбце:

Rv0001 -0.581372258 -0.147459774 0.548735372 1.001137114 Rv0002 -1.555384307 0.386044242 0.046125098 -0.06681665

Я хотел бы иметь третий файл output, который совпадает с file2, за исключением каждого Rv * заменяется кодом (-ами). Например, в приведенном выше примере output будет выглядеть так:

T -0.581372258 -0.147459774 0.548735372 1.001137114 S -1.555384307 0.386044242 0.046125098 -0.06681665 L -1.555384307 0.386044242 0.046125098 -0.06681665

Это закрытие, которое у меня есть, но оно не работает.

#!/bin/bash while read p; do gene=$( awk '{print $1}' ) grep "$gene" $2 | while read -r line ; do function_code=$( awk '{print $(NF-1)}' ) new_row=$(echo $line | sed -e 's/$gen/$function_code/g' ) echo $new_row >> output done done < $1

My файлы имеют около десяти тысяч строк, если это имеет значение.

1
задан 3 June 2017 в 11:47

3 ответа

Прежде всего, ваш file1 не имеет никакого конкретного разделителя, во-вторых, у вас есть такие же клавиши с разными значениями, как "Rv0002 S" и "Rv0002 L".

Как показывает ваш желаемый результат, я считаю все строки будут отсортированы, и вы просто захотите объединить эти два файла вместе.

Вот что я хотел бы сделать:

sed -r "s/(^Rv[0-9]+\s).*(\s+[A-Z]\s+).*/\1\2/" file1 > list1

Он создаст список ключей для меня вроде: [ ! d3]

$ cat list1
Rv0001  T       
Rv0002  S       
Rv0002  L  

В конце концов я присоединяюсь к ним и вырезаю нужные поля:

$ join list1 file2 | cut -f2- -d' '
T  -0.581372258 -0.147459774 0.548735372 1.001137114
S  -1.555384307 0.386044242 0.046125098 -0.06681665
L  -1.555384307 0.386044242 0.046125098 -0.06681665
3
ответ дан 22 May 2018 в 21:56
  • 1
    По электронной почте Ой! моя ошибка, первая колонка в обоих file1 и file2 одинакова, я только что обновил ее. Но, как вы упомянули, значения не уникальны (возможно, «ключ, значение» здесь является неправильным) – havij 3 June 2017 в 00:30
  • 2
    Обновлен мой ответ;) – Ravexina 3 June 2017 в 00:33
  • 3
    что, если есть Rv000x, который существует в file1, но не в file2? lol, извините, я не знал этого, пока не получил ошибку join: myFile:93: is not sorted: Rv0078 K (я sort их издал). – havij 3 June 2017 в 01:33
  • 4
    Если в file1 есть строка, которая не находится в file2, она игнорирует эту строку и не жалуется на нее. попробуйте join --nocheck-order list1 file2. – Ravexina 3 June 2017 в 08:23
  • 5
    Вы можете сделать все с помощью одной цепи труб: sed -r 's/(^Rv[0-9]+\s).*(\s+[A-Z]\s+).*/\1\2/' file1 | join - file2 | cut -f2- -d' ' – David Foerster 3 June 2017 в 11:49

Прежде всего, ваш file1 не имеет никакого конкретного разделителя, во-вторых, у вас есть такие же клавиши с разными значениями, как "Rv0002 S" и "Rv0002 L".

Как показывает ваш желаемый результат, я считаю все строки будут отсортированы, и вы просто захотите объединить эти два файла вместе.

Вот что я хотел бы сделать:

sed -r "s/(^Rv[0-9]+\s).*(\s+[A-Z]\s+).*/\1\2/" file1 > list1

Он создаст список ключей для меня вроде: [ ! d3] $ cat list1 Rv0001 T Rv0002 S Rv0002 L

В конце концов я присоединяюсь к ним и вырезаю нужные поля:

$ join list1 file2 | cut -f2- -d' ' T -0.581372258 -0.147459774 0.548735372 1.001137114 S -1.555384307 0.386044242 0.046125098 -0.06681665 L -1.555384307 0.386044242 0.046125098 -0.06681665
3
ответ дан 18 July 2018 в 12:15

Прежде всего, ваш file1 не имеет никакого конкретного разделителя, во-вторых, у вас есть такие же клавиши с разными значениями, как "Rv0002 S" и "Rv0002 L".

Как показывает ваш желаемый результат, я считаю все строки будут отсортированы, и вы просто захотите объединить эти два файла вместе.

Вот что я хотел бы сделать:

sed -r "s/(^Rv[0-9]+\s).*(\s+[A-Z]\s+).*/\1\2/" file1 > list1

Он создаст список ключей для меня вроде: [ ! d3] $ cat list1 Rv0001 T Rv0002 S Rv0002 L

В конце концов я присоединяюсь к ним и вырезаю нужные поля:

$ join list1 file2 | cut -f2- -d' ' T -0.581372258 -0.147459774 0.548735372 1.001137114 S -1.555384307 0.386044242 0.046125098 -0.06681665 L -1.555384307 0.386044242 0.046125098 -0.06681665
3
ответ дан 24 July 2018 в 19:56

Другие вопросы по тегам:

Похожие вопросы: