vlookup функционируют в Unix

Я предположил, что извлеченные строки региона следуют за строками CDS для каждого выравнивания.

Скопируйте этот код в script.pl:

use strict;
use warnings;

my $input = 1;
my @field = ('CDS','extracted region');
my (%data);
my (%counter);
&zero;

while ( <> ) { 

    ## Omit header.
    next if $. == 1;
    next if $. == 2;

    ## Remove last '\n'.
    chomp;

    ## Split line in tabs.
    my @f = split /\t/;

    ## Is loop over?
    if ( $f[2] =~ /$field[0]/ && $counter{$field[1]} > 1 )
    {
    &comparing;
    &zero;
    }

    ## Count number of $field[0] and $field[1] line
    $counter{$f[2]}++;

    ## Storing data
    @{$data{$f[2]}[$counter{$f[2]}]} = @f;
}

&comparing;

sub zero {
    $data{$field[0]} = [];
    $data{$field[1]} = [];
    $counter{$field[0]} = 0;
    $counter{$field[1]} = 0;
}

sub comparing {
    ## Is same line ($field[0] and $field[1])? if ( $input == 1 )
    if ( $counter{$field[0]} ==  $counter{$field[1]} || $input == 2 )
    {
    &recover;
    &stamp;
    }
}

sub recover {
    my $pos = &input2(0,0)  if ( $input == 2 );
    for my $i ( 1 .. $#{ $data{$field[0]} } ) {
    &input1($i) if ( $input == 1 );
    &input2($i,$pos) if ( $input == 2 );
    }
}

sub input1 {
    #;Extracted interval="376914 -> 377067"
    $data{$field[1]}[$_[0]][8] =~ m/;Extracted interval="(\d+) /;
    $data{$field[0]}[$_[0]][3] = $1;
    $data{$field[1]}[$_[0]][8] =~ m/;Extracted interval="\d+ -> (\d+)"/;
    $data{$field[0]}[$_[0]][4] = $1;
}

sub input2 {
    if ( $_[0] == 0 )
    {
    #;Extracted interval="2010140 <- 2024072"
    $data{$field[1]}[1][8] =~ m/;Extracted interval="(\d+) /;
    $1;
    }
    else
    {
    $data{$field[0]}[$_[0]][3] = $_[1] + $data{$field[0]}[$_[0]][3];
    $data{$field[0]}[$_[0]][4] = $_[1] + $data{$field[0]}[$_[0]][4];
    }
}

sub stamp {
    for my $i ( 1 .. $#{ $data{$field[0]} } ) {
    for my $j ( 0 .. $#{ $data{$field[0]}[$i] } ) {
        print "$data{$field[0]}[$i][$j]\t";
    }
    print "\n";
    }
}

Вы могли запустить скрипт жемчуга с input1.txt:

perl script.pl input1.txt > output1.txt

если Вы изменяете строку:

my $input = 1;

с

my $input = 2;

Вы могли запустить скрипт жемчуга с input2.txt:

perl script.pl input2.txt > output2.txt

Сценарий Perl мог также получать два аргумента: входной файл и тип [12].

Править

В https://stackoverflow.com/questions/1730333/how-do-i-use-getoptions-to-get-the-default-argument существуют некоторые методы, собирающиеся получать аргументы.

Если Вы изменяете строку:

my $input = 1;

с

my $input = 1;
$input = $ARGV[1] if defined $ARGV[1];

Вы могли запустить скрипт жемчуга с input1.txt:

perl script.pl input1.txt > output1.txt

или

perl script.pl input1.txt 1 > output1.txt

и Вы могли запустить скрипт жемчуга с input2.txt:

perl script.pl input2.txt 2 > output2.txt

4
28.08.2013, 17:14
5 ответов

Нет общей функции, которая сделает a vlookup как общая функция в Unix. Скорее Вы даете "кирпичи", из которых можно создать решения проблем в более специализированном подходе. Эти "кирпичи" являются инструментами такой как grep, awk, и sed среди других.

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

vlookup.awk

FNR==NR{
  a[$1]=$2
  next
}
{ if ($1 in a) {print $1, a[$1]} else {print $1, "NA"}  }

Пример

$ awk -f vlookup.awk file2 file1
1GR_P1:001PI 1GR_P1:001PI
:040VG_L1 NA
:001PO_L3 NA
1JPI_P1:001PO_L1 1JPI_P1:001PO_L1
1JPI_P1:001PO_L2 1JPI_P1:001PO_L2

Можно использовать column управляйте к очистке выводом:

$ awk -f vlookup.awk file2 file1 | column -t
1GR_P1:001PI      1GR_P1:001PI
:040VG_L1         NA
:001PO_L3         NA
1JPI_P1:001PO_L1  1JPI_P1:001PO_L1
1JPI_P1:001PO_L2  1JPI_P1:001PO_L2

Подробнее

Вышеупомянутое awk сценарий берет все содержание file2 в массив, который индексируется с помощью значения в качестве ключа.

a[$1]=$1

Однажды file2 был считан в массив a, file1 затем не стал через строку за один раз, и решение принято. Если значение первого столбца file1 присутствует в массиве a, затем соответствующее значение в file2столбец 2 печатается наряду с file1столбец 1. Если это не присутствует затем, сообщение "NA" печатается.

7
27.01.2020, 20:49
  • 1
    Верит для соответствия требованию OP, которое необходимо изменить a[$1]=$1 кому: a[$1]=$2 –  iruvar 28.08.2013, 18:10
  • 2
    $1 column1 и $2 column2? Или каково различие между a[$1]=$1 и a[$1]=$2 –  HattrickNZ 18.08.2015, 06:07
  • 3
    $1 и $2 в vlookup.awk столбцы, но мы только устанавливаем a[$1]==$2 когда FNR равен НОМЕРУ. Посмотрите этот пример на ТАК для лучшего описания этого использования метода awk: stackoverflow.com/questions/15065818/compare-files-with-awk. –  slm♦ 18.08.2015, 08:31

Для определенных примеров данных Вы обеспечили, следующее должно работать. Это загружает поле 2 из File2 в массив, индексированный полем 1. File1 затем циклично выполняется через и соответствия массива или NA печатаются

awk 'NR == FNR{a[$1] = $2;next}; {print $1, $1 in a?a[$1]: "NA"}' File2 File1
1
27.01.2020, 20:49

POSIX join(1) команда делает что-то очень похожее на VLOOKUP(), с протестом, что входные файлы должны уже быть отсортированы на столбцах, к которым присоединятся.

$ sort file1 > sfile1
$ sort file2 > sfile2
$ join -a1 sfile1 sfile2
1GR_P1:001PI 1402UC
1JPI_P1:001PO_L1 1401UC
1JPI_P1:001PO_L2 1401UC
:001PO_L3
:040VG_L1

К сожалению, Ваш пример действительно не иллюстрирует как join работы, с тех пор file1 содержит всего один столбец.

Для получения точно вывода, Вы хотите, Вы могли записать простой сценарий с помощью ассоциативных массивов, с помощью awk например, как другие предположили.

1
27.01.2020, 20:49

Если Вы ищете что-то, что работает из командной строки, взглянули на awk. Это - ОЧЕНЬ популярная программа, используемая для всех видов парсинга операций. http://en.wikipedia.org/wiki/AWK

Кроме того, трудно упомянуть, что анализировало текст в UNIX без упоминания grep. grep используется для regex совпавшего текста. В то время как не нужный для этого конкретного приложения это в конечном счете пригодится при выполнении большого текстового парсинга. http://en.wikipedia.org/wiki/Grep

Используя colrm столбцы текста могут быть сокращены из потока. Это может быть полезно при наличии затруднений при изоляции текста с awk.

sedто, что Вы захотите использовать, если текст для парсинга будет очень длинен или если awk не может легко выполнить то, что Вы хотите. Sed на Википедию

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

0
27.01.2020, 20:49

Попробуйте смесь awk и советов (чрезвычайно быстрое хранилище значения ключа NoSQL с открытым исходным кодом. См. http://redis.io для деталей).

Используйте awk для парсинга Ваших 2 файлов для генерации команд советов.

Передайте результат по каналу 2 awk сценариев в удар для выполнения их. Вот именно :-)

Шаг за шагом:

Генерируйте свои операторы "SET" советов путем парсинга "File2" как это:

awk '{print "redis-cli SET KEY:" $1 " \"" $2"\""}' File2
redis-cli SET KEY:1JPI_P1:001PO_L1 "1401UC"
redis-cli SET KEY:1JPI_P1:001PO_L2 "1401UC"
redis-cli SET KEY:1HIK_P2:001ER "1402UC"
redis-cli SET KEY:1GR_P1:001PI "1402UC"

Передайте свои сгенерированные операторы "SET" советов по каналу в удар для выполнения их:

awk '{print "redis-cli SET KEY:" $1 " \"" $2"\""}' File2 |\
 bash
OK
OK
OK
OK

Генерируйте свои операторы "GET" советов путем парсинга "File1" как это:

awk '{print "printf \"" $1 " \" && redis-cli GET KEY:" $1}' File1
printf "1GR_P1:001PI " && redis-cli GET KEY:1GR_P1:001PI
printf ":040VG_L1 " && redis-cli GET KEY::040VG_L1
printf ":001PO_L3 " && redis-cli GET KEY::001PO_L3
printf "1JPI_P1:001PO_L1 " && redis-cli GET KEY:1JPI_P1:001PO_L1
printf "1JPI_P1:001PO_L2 " && redis-cli GET KEY:1JPI_P1:001PO_L2

Теперь запросите советы путем передачи по каналу операторов "GET" советов, сгенерированных выше в удар:

awk '{print "printf \"" $1 " \" && redis-cli GET KEY:" $1}' File1 |\
 bash
1GR_P1:001PI "1402UC"
:040VG_L1 (nil)
:001PO_L3 (nil)
1JPI_P1:001PO_L1 "1401UC"
1JPI_P1:001PO_L2 "1401UC"

Остерегайтесь этого, необходимо ли выйти из двойных кавычек в строках с единственными обратными косыми чертами, чтобы избежать, чтобы советы импортировали ошибки (см. ответ slm в том, Как я изменяю это решение для Perl так, чтобы это заменило встроенными двойными кавычками с одинарными кавычками?). Можно также использовать одинарные кавычки для инкапсуляции значений для импорта в советы, если значения содержат много двойных кавычек.

HTH

bernie

0
27.01.2020, 20:49

Теги

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