Это извлечет все символы перед последним «двоеточием» и удалит скобки [ ] как в приведенном вами примере.
rev <yourfile.txt | cut -d: -f2- | rev | tr -d '[]'
Замените yourfile.txt на имя вашего файла или удалите слово <yourfile.txt
, чтобы прочитать стандартный вывод.
Одним из вариантов может быть использование system()
непосредственно изнутриawk
:
Подтвердить, запросив устройство изlsusb
:
lsusb | awk '/Tascam.*Hub$/{ system("lsusb -d " $6) }'
Это займет vendor:product
, (поле 6 ), из целых строк, соответствующих:
Tascam<Anything zero or more times>Hub<END-OF-LINE>
и выполнить:lsusb -d vendor:product
Это будет выполняться навсехсоответствующих концентраторах Tascam .
На самом деле звонитеusbreset
:
lsusb | sudo awk '/Tascam.*Hub$/{ system("/usr/bin/usbreset " $6) }'
Или лучше выйти, если ошибка:
lsusb | sudo awk '/Tascam.*Hub/{ if (system("/usr/bin/usbreset " $6)) exit 1 }'
Так какsystem(expression)
возвращает статус выхода команды, а 0
является успешным, можно использовать if ()
для проверки, что если статус <> 0, он продолжит с exit 1
. Выйдите с чем-то другим, затем 0
, чтобы сигнализировать об ошибке.
При необходимости используйте != 0
, если вам так удобнее читать. И, возможно, выбросить ошибку.
lsusb | sudo awk '
/Tascam.*Hub/ {
if (system("/usr/bin/usbreset " $6) != 0) {
print "usbreset failed" >"/dev/stderr"
exit 1
}
}'
Если вы хотите фильтровать по номеру -устройства, лучше всего поместить его в оболочку -скрипт (, которую вы, скорее всего, в любом случае ), а затем сделать что-то вроде:
#! /bin/sh -
# Check argument is given
if [ -z "$1" ]; then
printf 'Missing device number\n' >&2
exit 1
fi
# Check sudo or abort
sudo echo >/dev/null || exit 1
lsusb |
sudo awk -v dev="$1" '
BEGIN {
dev = sprintf("%03d:", dev)
eno = 1
}
$4 == dev && /Tascam.*Hub/ {
if (system("/usr/bin/usbreset " $6) != 0) {
eno = 2
} else {
eno = 0
}
# Exit on first match of device-number + name
exit
}
END {
if (eno == 0)
print "OK"
else if (eno == 1)
print "No device found" >"/dev/stderr"
else if (eno == 2)
print "usbreset failed" >"/dev/stderr"
exit eno
}'
usbreset
Невозможно установить его локально, но похоже, что некоторые аргументы принимают как:
/dev/bus/usb/<bus>/<device-number>
В этом случае вам может понадобиться что-то вроде:
# Testing:
system(sprintf("ls -l /dev/bus/usb/%03d/%03d", $2, $4))
# Testing:
system(sprintf("/usr/bin/usbreset /dev/bus/usb/%03d/%03d", $2, $4))
grep
, когда awk
следует за ним, является ненужным шагом. awk
соответствует регулярным выражениям — и в данном случае это простая строка (в вашем коде ). awk '/^foo/{ this line starts with foo }'
и т. д.
printf $6 "\n"
Похоже, вы хотите напечатать $6
+ перевод строки -. Это может быть либо:
print $6
printf "%s\n", $6
Он также указывает awk использовать $6
в качестве строки формата. Это может испортиться, и в целом это нехорошо. Если бы $6
было, например, foo%dbar
, awk ожидал бы цифру в качестве параметра. и т. д.
printf "/usr/bin/usbreset %d", $6
,скажем "печатная цифра" и здесь значение "6 долларов" . Поскольку поле шесть равно hex:hex
, оператор printf будет печатать только первые цифры, если они есть, иначе ноль. 12a1:06df
->12
a112:3619
->0
Похоже, это то, что вы пытаетесь сделать:
$ cat file | awk '$7=="Tascam"{print $6}' | xargs echo sudo /usr/bin/usbreset
sudo /usr/bin/usbreset 1604:10c0
или:
$ echo sudo /usr/bin/usbreset "$(cat file | awk '$7=="Tascam"{print $6}')"
sudo /usr/bin/usbreset 1604:10c0
Замените cat file
на lsusb
и удалите echo
, когда вы довольны результатом и хотите фактически выполнить команду, отображаемую в данный момент.