Match File1 with File 2

Всякий раз, когда вы видите записи, разделенные пустыми строками («абзацы», если хотите), «режим абзаца» Perl часто является хорошим решением:

$ perl -00lpe 'if(/NAME#AAAA/){s/\bAGE\s/#$&/; s/$/\nAGE NIL/;}' file
NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
#AGE 9
AGE NIL

NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL

Объяснение

  • -00 : это активирует режим абзаца Perl , где каждый «абзац» (группа непустых строк до пустого) рассматривается как «строка».
  • -l : удаляет завершающие символы новой строки из каждой входной записи (каждый абзац) и добавляет новую строку к каждому вызову print . -pe : print каждая входная запись после обработки применяет к нему сценарий, заданный параметром -e .

Таким образом, эти флаги заставляют perl читать входной файл, применять сценарий к каждой записи и затем печатать результат. Сам сценарий выполняет:

  • if (/ NAME # AAAA /) : если эта запись соответствует NAME # AAAA .
  • s / \ bAGE \ s / # $ & / : s / foo / bar / - это оператор подстановки. Он заменит foo на bar . Здесь я заменяю AGE самим собой, которому предшествует # . \ b соответствует границам слов и исключает такие вещи, как ADAGE из соответствия. $ & - это специальная переменная, означающая «все, что было найдено. Итак, s / \ bAGE \ s / # $ & / заменит AGE на #AGE .
  • s / $ / \ nAGE NIL / : $ соответствует концу записи. Таким образом, замена его на что-то другое будет добавляться в конец Эта команда добавляет AGE NIL в конец сопоставленной записи.

Обратите внимание, что все операции здесь чувствительны к регистру. Если вам нужно сопоставление без учета регистра, используйте вместо него следующее:

perl -00lpe 'if(/NAME#AAAA/i){s/\bAGE\s/#$&/i; s/$/\nAGE NIL/i;}' file
-1
01.07.2017, 00:27
2 ответа
perl -lane '
   @ARGV and $h{$F[0]}=$F[1],next;
   print join $", map { $_, $h{$_} // "NA" } @F;
' File2 File1

Результаты

GeneA Ensembl1 GeneB Ensembl2
GeneA Ensembl1 GeneD NA
GeneC Ensembl3 GeneB Ensembl2

Работа

  • Сначала укажите File2, затем File1 в списке аргументов для Perl.
  • Создайте хэш %hс ключами GeneA, GeneB и т. д. => значения представляют собой ансамбли из File2. Обратите внимание, что при обработке File2 @ARGV имеет один элемент, поэтому @ARGV в скалярном контексте возвращает значение true.
  • Во время чтения -файла File1 значение @ARGV уменьшается до нуля, поэтому первая строка не оценивается. Во второй строке будут напечатаны поля после соответствующего преобразования сопоставления и объединены пробелами ($" по умолчанию равно пробелу ).
0
28.04.2021, 23:59

awkрешение:

awk 'NR==FNR{ a[$1]=$2; next }
     { $1=$1 FS (($1 in a)? a[$1]:"NA"); $2=$2 FS (($2 in a)? a[$2]:"NA"); }1' File2 File1

Вывод:

GeneA Ensembl1 GeneB Ensembl2
GeneA Ensembl1 GeneD NA
GeneC Ensembl3 GeneB Ensembl2
2
28.04.2021, 23:59

Теги

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