Похоже, единственный способ отключить это устройство - физически отсоединить его (если это вообще возможно).
Я читал о Linux sysfs
и о том, как его можно использовать для опроса устройств и т.д., а также нашел это на kernel.org. В USB существует возможность отключения питания определенных портов USB-концентратора, однако когда я выполняю sudo lsusb
на рассматриваемом концентраторе, его дескриптор сообщает, что индивидуальное питание портов недоступно. (USB 1.0).
Приведенный ниже сценарий представляет собой явное более "ручное" решение, которое не использует регулярные выражения, но выполняет работу с некоторыми дополнительными соображениями. Ключом к его работе является то, что скрипт открывается для чтения любого файла, который мы предоставили в командной строке, перебирает каждый символ в каждой строке, пытаясь найти скобки. Если мы видим скобки, мы записываем то, что внутри, и, отбрасывая запятые, решаем, числовая это строка или нет. Если это числовая строка - записанные элементы попадают в список слов, который затем перестраивается в строку с помощью функции .join()
с ", "
в качестве разделителя. Довольно просто.
#!/usr/bin/env python3
import sys
with open(sys.argv[1]) as fd:
for line in fd:
# we're going to store everything into list of words
# and record individual characters into 'item' string
# and rebuild everything as we go.
words = []
item_found = False
item = ""
counter = 0
for char in line:
# if we see ( or [ we start recording chars
# difference is that [ means item already been edited
# so no need to do anything - just put it into words list
# as is
if char == "(" or char == "[":
item_found = True
counter = counter + 1
continue
if char == ")":
item_found = False
if item.replace(",","").isdigit():
words.append("[" + item + "]")
else:
words.append("("+item+")")
item = ""
if char == "]":
item_found = False
item = item + char
words.append("[" + item)
item = ""
if item_found:
item = item + char
# if we didn't see any open brackets or no closing brackets
# just print the line as is - otherwise give us the altered one
if counter == 0 or item_found:
print(line.strip())
else:
print(", ".join(words))
Я взял на себя смелость ввести OP, чтобы добавить дополнительные 2 строки, которые включают пару разных тестовых случаев.
$ # original input file
$ cat input.txt
(1), (3), (1,2,3), (1,2,3,4,5,6,7,8,9), (Fig1) (Fig1,Fig2), (Table-1, Table-2)
(table-25),[1,2,3],(figure-35)
(figure-1),(figure-2)
$ # script output
$ ./change_brackets.py input.txt
[1], [3], [1,2,3], [1,2,3,4,5,6,7,8,9], (Fig1), (Fig1,Fig2), (Table-1, Table-2)
(table-25), [1,2,3], (figure-35)
(figure-1), (figure-2)
С 40 000 строк текста он работает довольно быстро:
$ wc -l big_input.txt
40000 big_input.txt
$ time ./change_brackets.py big_input.txt > /dev/null
0m01.64s real 0m01.60s user 0m00.01s system
Возможное предложение по улучшению (и решению одной из вещей, упомянутых Стефаном ) заключается в изменении if item.replace( ",","").isdigit()
в строку if item.replace(",","").replace(".","").isdigit()
. Это позволит нам работать и с числами с плавающей запятой (например, 3,1415).
Длинный ? да. Явный? да. Работает ? Ну да.
sed -E 's/[(](([0-9]+,?)+)[)]/[\1]/g'
sed -e 's/(\(\([0-9]\{1,\},\{0,\}\)\{1,\}\))/[\1]/g'
Ищем регулярное выражение [0-9]+,? встречается хотя бы один раз и одновременно ограничен скобками ( и ). В случае успеха внешние скобки меняются на [ ].
Второй оператор sed — это POSIX-версия предыдущего.
С sed
:
sed 's/(\([0-9,]*\))/[\1]/g' filename.txt
[0-9,]*
— регулярное выражение, соответствующее любому количеству цифр и запятых. Я заключил его в \(\)
, чтобы можно было повторно использовать его в строке замены как \1
. Простые скобки без обратной косой черты обозначают сами себя.Они заменяются на []
(которые не имеют особого значения в строке замены).