Перебор выходных данных awk

Я заработал, используя hidapi для python . В конце концов, это было очень просто, мне просто не хватало инструмента.

Вот полный сценарий, если кому понадобится помощь:

from __future__ import print_function

import hid
import time
import uinput

MAPPING = {
    'green': uinput.BTN_0,
    'red': uinput.BTN_1,
    'yellow': uinput.BTN_2,
    'blue': uinput.BTN_3,
    'orange': uinput.BTN_4,
    'tilt': uinput.BTN_SELECT,  # SELECT
    'start': uinput.BTN_START,  # START
    'select': uinput.BTN_SELECT,  # SELECT
    'whammy': uinput.ABS_X,  # WHAMMY
    'strumdown': uinput.BTN_DPAD_DOWN,
    'strumup': uinput.BTN_DPAD_UP,
}

DEVICE = uinput.Device(MAPPING.values())

# enumerate USB devices

for d in hid.enumerate():
    keys = list(d.keys())
    keys.sort()
    for key in keys:
        print("%s : %s" % (key, d[key]))
    print()

# try opening a device, then perform write and read


def diff(new_arr, old_arr):
    for i in range(len(new_arr)):
        if new_arr[i] != old_arr[i]:
            yield (i, new_arr[i]) 


try:
    print("Opening the device")

    h = hid.device()
    h.open(0x054c, 0x0268)  # VendorID/ProductID

    print("Manufacturer: %s" % h.get_manufacturer_string())
    print("Product: %s" % h.get_product_string())
    print("Serial No: %s" % h.get_serial_number_string())

    # enable non-blocking mode
    h.set_nonblocking(1)

    # write some data to the device
    print("Write the data")
    h.write([0, 63, 35, 35] + [0] * 61)

    # wait
    time.sleep(0.05)

    # read back the answer
    print("Read the data")
    previous = None
    INPUT = {
        'green': False,
        'red': False,
        'yellow': False,
        'blue': False,
        'orange': False,
        'tilt': False,
        'start': False,
        'select': False,
        'whammy': False,
        'strumdown': False,
        'strumup': False,
    }

    def set_input(key, val, tmp):
        prev = INPUT[key]
        if tmp >= val:
            tmp -= val
            INPUT[key] = True
        else:
            INPUT[key] = False

        if prev != INPUT[key]:
            # SEND EVENT
            DEVICE.emit(MAPPING[key], INPUT[key])
            pass

        return tmp

    counter = 0
    while True:
        try:
            time.sleep(0.001)
            d = h.read(64)
            counter += 1
            if d:
                if previous and d != previous:
                    for ret in diff(d, previous):
                        if ret[0] == 7:
                            DEVICE.emit(MAPPING['whammy'], ret[1])

                        if ret[0] == 2:
                            tmp = ret[1] - 128
                            tmp = set_input('strumdown', 64, tmp)
                            tmp = set_input('strumup', 16, tmp)
                            tmp = set_input('start', 8, tmp)
                            tmp = set_input('select', 1, tmp)

                        if ret[0] == 3:
                            tmp = ret[1]
                            tmp = set_input('orange', 128, tmp)
                            tmp = set_input('blue', 64, tmp)
                            tmp = set_input('red', 32, tmp)
                            tmp = set_input('yellow', 16, tmp)
                            tmp = set_input('green', 2, tmp)
                            tmp = set_input('tilt', 1, tmp)

                previous = d
            else:
                continue
        except KeyboardInterrupt:
            break
        print(counter, end="\r")
        # print(INPUT)

    print("Closing the device")
    h.close()

except IOError as ex:
    print(ex)
    print("You probably don't have the hard coded device. Update the hid.device line")
    print("in this script with one from the enumeration list output above and try again.")

print("Done")

1
09.07.2020, 17:09
5 ответов

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

>header
sequence

И вы хотите извлечь заголовки, удалить >и любые 'и разделить их на ,или ;. Если это так, вы можете сделать это непосредственно в самих файлах fasta:

$ sed -n '/^>/{s/>//; s/[,:]/\n/gp}' *.fasta | tr -d "';"
NODE_3028138_length_2215_cov_1.9513_ID_6056275
NODE_6264558_length_375_cov_4.0000_ID_12529115
NODE_3552704_length_509_cov_1.0000_ID_7105407
NODE_4456634_length_439_cov_1.9597_ID_8913267
NODE_4457268_length_491_cov_0.9657_ID_8914535

Пояснение

  • sed -n:подавлять нормальный вывод, ничего не печатать, если это явно не указано.
  • /^>/{something}:, если эта строка начинается с >, выполните something.
  • s/^>//;:удалить >с начала строки.
  • s/[,:]/\n/gp:замените все (все из-за gв конце),или :с новой строкой (\n), а затем напечатайте (вы печатаете из-за pв конце.
  • tr -d "';":удалить любые ;или '.

В своем комментарии вы сказали, что пытались 'i=$(sed "s/[:,]/\n/g" <<< $i)'и получили только пробелы, а не новые строки. Это потому, что вы тогда запустили echo $iвместо echo "$i", поэтому новые строки были потеряны.


Если вам действительно нужно сделать это для отображаемой коллекции строк, вы можете сделать:

for i in ">NODE_3028138_length_2215_cov_1.9513_ID_6056275:NODE_6264558_length_375_cov_4.0000_ID_12529115';" ">NODE_4338305_length_1150_cov_1.0000_ID_8676609;" ">NODE_3552704_length_509_cov_1.0000_ID_7105407:NODE_4456634_length_439_cov_1.9597_ID_8913267',NODE_4457268_length_491_cov_0.9657_ID_8914535';"; do 
    sed -n '/^>/{s/>//; s/[,:]/\n/gp}' <<<"$i" | tr -d "';" ; 
done
NODE_3028138_length_2215_cov_1.9513_ID_6056275
NODE_6264558_length_375_cov_4.0000_ID_12529115
NODE_3552704_length_509_cov_1.0000_ID_7105407
NODE_4456634_length_439_cov_1.9597_ID_8913267
NODE_4457268_length_491_cov_0.9657_ID_8914535
3
18.03.2021, 23:20

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

Предполагая, что ваши строки на самом деле находятся в файле input.txt, следующий вызов awkсделает свое дело:

awk '{gsub(/[:>,;\047]/,""); n=split($0,a,/NODE/); for (i=2;i<=n;i++) printf("NODE%s\n",a[i])}' input.txt
  • Это сначала заменит все «лишние» символы, используяgsub()(\047— одинарную кавычку ', которую нельзя дословно поместить в строку команды -, поскольку сами команды awkнаходятся внутри одиночной -кавычки ).
  • Затем он разделит оставшуюся строку на поля по шаблону NODEи сохранит результат в массиве a.
  • Любое «поле», за исключением самого первого (, которое будет строкой перед первым вхождением NODE), печатается отдельно с добавлением NODE.

Для вашего примера результат ввода:

awk '{gsub(/[:>,;\047]/,""); n=split($0,a,/NODE/); for (i=2;i<=n;i++) printf("NODE%s\n",a[i])}' input.txt
NODE_3028138_length_2215_cov_1.9513_ID_6056275
NODE_6264558_length_375_cov_4.0000_ID_12529115
NODE_4338305_length_1150_cov_1.0000_ID_8676609
NODE_3552704_length_509_cov_1.0000_ID_7105407
NODE_4456634_length_439_cov_1.9597_ID_8913267
NODE_4457268_length_491_cov_0.9657_ID_8914535

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

awk '{gsub(/[:>,;\047]/,""); if ((n=split($0,a,/NODE/))<3) next; for (i=2;i<=n;i++) printf("NODE%s\n",a[i])}' input.txt
NODE_3028138_length_2215_cov_1.9513_ID_6056275
NODE_6264558_length_375_cov_4.0000_ID_12529115
NODE_3552704_length_509_cov_1.0000_ID_7105407
NODE_4456634_length_439_cov_1.9597_ID_8913267
NODE_4457268_length_491_cov_0.9657_ID_8914535
2
18.03.2021, 23:20

Пробовал с помощью нижеприведенного метода Python

#!/usr/bin/python
import re
m=re.compile(r'[:;,]')
k=open('filename','r')
for i in k:
    co=i.count("NODE")
    if co > 1:
        q=i.strip()
        k=re.sub(m,"\n",q)
        print k.strip().replace("'","").replace(">","")

выход

NODE_3028138_length_2215_cov_1.9513_ID_6056275
NODE_6264558_length_375_cov_4.0000_ID_12529115
NODE_3552704_length_509_cov_1.0000_ID_7105407
NODE_4456634_length_439_cov_1.9597_ID_8913267
NODE_4457268_length_491_cov_0.9657_ID_8914535

awk :Лучшее решение, представленное в awk, это просто моя попытка

awk '{print $0,gsub("NODE",$0)}' filename| awk '$NF >1 {print $1}'| sed "s/[;:,]/\n/g"|sed '/^$/d'| sed "s/[\>']//g"
0
18.03.2021, 23:20

Если у вас есть gawkи вы не возражаете против пустой строки в начале, вы можете

  • составить RSдля потребления '*;\n, который очищает конец каждой строки
  • составить FSдля использования комбинаций[>;,']+
  • составить OFSдля предоставления \nи
  • установите ORSна пустое значение.

Это означает, что пустое$1(поле перед>)дает вам \nмежду записями, если вы перекомпонуете $0на OFSс помощью $1=$1. Кроме этого просто printвезде, где у вас естьNF>2

awk -F"[>:,']+" -v OFS="\n" -v RS="'*;\n" -v ORS="" 'NF>2{$1=$1; print }END{print "\n"}' file

NODE_3028138_length_2215_cov_1.9513_ID_6056275
NODE_6264558_length_375_cov_4.0000_ID_12529115
NODE_3552704_length_509_cov_1.0000_ID_7105407
NODE_4456634_length_439_cov_1.9597_ID_8913267
NODE_4457268_length_491_cov_0.9657_ID_8914535 
0
18.03.2021, 23:20

Используя редактор sed, мы можем сгенерировать желаемый результат следующим образом.

sed \
  -e '/\n/{/^\n/!P;D;}'                    \
  -e "/^>NODE_.*NODE/ y/>;:,'/\n\n\n\n\n/" \
  -e '/\n/G;D'                             \
file

Результаты:

NODE_3028138_length_2215_cov_1.9513_ID_6056275
NODE_6264558_length_375_cov_4.0000_ID_12529115
NODE_3552704_length_509_cov_1.0000_ID_7105407
NODE_4456634_length_439_cov_1.9597_ID_8913267
NODE_4457268_length_491_cov_0.9657_ID_8914535

Метод работы:

  • Только строки, содержащие как минимум два узла NODE и начинающиеся с >NODE_Назовем их «интересными» линиями.Мы меняем каждое вхождение >;:,'на новую строку в каждой интересующей строке.
  • Затем добавьте новую строку к интересующим строкам на тот случай, если они не заканчиваются точкой с запятой. Команда Dдолжна инициировать неявный цикл и привести нас к первой строке кода sed.
  • В первой строке происходит все действие, и интересующая строка используется полностью, в то время как sed последовательно выдает УЗЛЫ, по одному на строку.
0
18.03.2021, 23:20

Теги

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