Я заработал, используя 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")
Показанные шаги не нужны. Если я правильно понимаю, вы начинаете с набора файлов 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
Следующее решение несколько грубое, но должно работать. Предполагается, что, как показано в вашем образце ввода, все узлы начинаются со строки 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
Пробовал с помощью нижеприведенного метода 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"
Если у вас есть 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
Используя редактор 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_
Назовем их «интересными» линиями.Мы меняем каждое вхождение >;:,'
на новую строку в каждой интересующей строке. D
должна инициировать неявный цикл и привести нас к первой строке кода sed.