Сравнение Индексов двух строк

Установка x11vnc sudo-apt install x11vnc.

Если существует пользователь, уже вошел в систему выполненный x11vnc -display :0

Если никто не зарегистрирован, и Вы знаете путь к своему текущему DM (менеджер по оформлению), работаете sudo x11vnc -auth /path/to/x11auth -display :0

Или можно попытаться предположить на подлинном файле x11vnc -auth guess -display :0

И... На всякий случай Вы плохо знакомы с VNC, эта ссылка получит Вас до быстрой скорости: http://www.wikihow.com/Use-VNC-Virtual-Network-Computing-to-Control-a-Computer-Remotely

3
28.08.2013, 04:08
5 ответов

Если Ваши строки не содержат новой строки, вот решение с помощью только инструменты POSIX. Это работает путем помещения всех символов на отдельную строку, архивирования этих двух файлов вместе и извлечения строк, где первый файл (теперь первый столбец) имел a *.

con_file=$(mktemp)
echo "$con" | sed -e 's/./&\
/g' >"$con_file"
prot_lines=$(echo "$prot" | sed -e 's/./&\
/g')
prot_extract=$(echo "$prot_lines" |
               paste -d "$con_file" - |
               sed -n 's/^* //p' |
               tr -d '\n')

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

echo "$prot" | awk -v filter="$con" '{
    for (i=1; i<=length; i++) {
        if (substr(filter, i, 1) == "*") printf "%c", substr($0, i, 1);
    }
}
END {printf "\n"}'

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

indices=$(echo "$con" |
          sed 's/\*\**/,&\n/g' |
          awk -F , 'BEGIN {start = 1}
                    /\*/ {start += length($1);
                          printf "%d-", start;
                          start += length($2);
                          printf "%d,", start - 1}')
indices=${indices%,}
echo "$prot" | cut "$indices"
1
27.01.2020, 21:32

Можно использовать этот сценарий Perl, чтобы сделать то, что Вы хотите:

#!/usr/bin/perl

$con  ='                        *   ******       *** ** *                  **         ';
$prot ='M-ASDFRMKAWRGMLMI----WSGRCYYYYHQFLIMASDFRMKAMKAWWSGRCYNSHPPAAQVFYWLGLLSDVAGSALEAQ';

@c_con = split(//, $con);
@c_prot = split(//, $prot);

@i_con = grep { $c_con[$_] eq '*' } 0 .. $#c_con;
map { print "index: $_, value: @c_prot[$_]\n" } @i_con;

Пример

Выполнение его произведет список индексов и значений в тех индексах в $prot.

$ ./extracvals.pl 
index: 24, value: R
index: 28, value: Y
index: 29, value: Y
index: 30, value: H
index: 31, value: Q
index: 32, value: F
index: 33, value: L
index: 41, value: M
index: 42, value: K
index: 43, value: A
index: 45, value: K
index: 46, value: A
index: 48, value: W
index: 67, value: G
index: 68, value: L

Как это работает?

Сценарий создает 2 строки, как описано OP, $con и $prot. Эти строки затем читаются в 2 массива, такие, что каждый символ в строке поднимает ячейку в массиве. Это сделано с помощью Perl split funciton:

@c_con = split(//, $con);
@c_prot = split(//, $prot);

2 новых массива, @c_con (содержит $con) и @c_prot (содержит $prot).

Мы затем используем Perl grep функционируйте для нахождения всех индексов в массиве @c_con это имеет значение '*'. Этот список индексов хранится в другом массиве, @i_con.

Наконец мы используем Perl map функционируйте для печати индексного значения и соответствующего значения в массиве @c_prot в данном индексе. map функция принимает каждое значение от массива @i_con, и оценивает команду в фигурных скобках:

{ print "index: $_, value: @c_prot[$_]\n" }

для каждого из этих значений. Индекс хранится во временной переменной Perl, $_, как мы map выполняет итерации через массив @i_con.

0
27.01.2020, 21:32

Я работал аналогичное решение slm (он победил меня к нему!), Но если OP не хочет кодировать все это в жемчуге:

#!/bin/sh

con="                        *   ******       *** ** *                  **"
prot="M-ASDFRMKAWRGMLMI----WSGRCYYYYHQFLIMASDFRMKAMKAWWSGRCYNSHPPAAQVFYWLGLLSDVAGSALEAQ"

# put the con and prot variables into our environment variables
export con prot

# then call perl
result=$(perl -e 'my @x = split(//, "$ENV{con}"); 
    my @i = grep { $x[$_] eq "*" } 0 .. $#x; 
    print join("", map { substr("$ENV{prot}", $_, 1) } @i );' )

# now we have your answer in $result
echo "$result"

# then once finished with con and prot, unset them from the environment
unset con prot

$ENV зарезервированная переменная в жемчуге, содержащем хеш всех имен переменной среды и значений, таким образом получая значение $prot (который мы использовали export установить его), может просто быть выбран через $ENV{prot}.

Вместо того, чтобы разделить массивы как slm сделал, я использовал substr который возвращает подстроку данной строки (первый аргумент) при смещении (2-й аргумент) длины набора (3-й аргумент). Кроме этого мы, казалось, использовали идентичные решения (довольно жуткий, выдавали музыку Зоны Сумерек) :)

0
27.01.2020, 21:32

Если мы можем использовать гну grep:

cut -c$(grep -Fbo '*' <<<_"$con" | cut -f1 -d: | paste -sd,) <<<"$prot"

Я уверен, что это может играться в гольф больше, но это хорошо работает. -bo причины grep для вывода (b) yte-смещения с (o) nly-соответствия (не целые строки), который как побочный эффект заставляет grep находить всеми соответствиями, не всего один на строку. Мы затем управляем этим в разделенный запятыми список чисел, к которым мы можем питаться как параметр командной строки cut. Раздражающая деталь - то, что grep думает, что индексы символа на основе 0, и сокращение думает, что они на основе 1, таким образом, мы должны сместиться $con одним символом; следовательно, _.

$ con="                        *   ******       *** ** *                  **"
$ prot="M-ASDFRMKAWRGMLMI----WSGRCYYYYHQFLIMASDFRMKAMKAWWSGRCYNSHPPAAQVFYWLGLLSDVAGSALEAQ"
$ printf "%s\n%s\n" "$con" "$prot"
                        *   ******       *** ** *                  **
M-ASDFRMKAWRGMLMI----WSGRCYYYYHQFLIMASDFRMKAMKAWWSGRCYNSHPPAAQVFYWLGLLSDVAGSALEAQ
$ cut -c"$(grep -Fbo '*' <<<_"$con" | cut -f1 -d: | paste -sd,)" <<<"$prot"
RYYHQFLMKAKAWGL
0
27.01.2020, 21:32

Простое решение, использующее функции оболочки Bash (видел a /bash тег в вопросе):

con="                        *   ******       *** ** *                  **"
prot="M-ASDFRMKAWRGMLMI----WSGRCYYYYHQFLIMASDFRMKAMKAWWSGRCYNSHPPAAQVFYWLGLLSDVAGSALEAQ"

i=0
# Iterate until the index is less than the con string length  
while [ $i -lt ${#con} ]
do 
    # Get the current element of the con "character array"  
    c=${con:$i:1}
    if [[ $c == '*' ]]
    then
        # Get the corresponding element from the prot character array  
        p=${prot:$i:1}
        echo $i, $c, $p
    fi
    i=$((i+1))
done

Вывод:

24, *, R
28, *, Y
29, *, Y
30, *, H
31, *, Q
32, *, F
33, *, L
41, *, M
42, *, K
43, *, A
45, *, K
46, *, A
48, *, W
67, *, G
68, *, L

Конечно, можно измениться echo оператор для управления, что печатается.

Источник: Bash: строка Разделения в символьный массив

0
27.01.2020, 21:32

Теги

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