возникает проблема при назначении var2. Он должен читать:
var2=$(expr substr "${var1}" 1 7)
причина кавычек состоит в том, что var1 имеет пробелы, которые путают substr, а 0 -> 1, потому что он начинает отсчет с 1.
Также есть некоторые проблемы с вашими цитатами:
#!/bin/bash
var1=$(lspci | grep -E "VGA|3D")
var2=$(expr substr "${var1}" 1 7)
var3=$(sudo lspci -v -s "${var2}")
echo "$var3"
Использование grep с помощью PCRE (-P):
lspci | grep -Po '^\s*\K\S+(?=\s+VGA\s)'
и
lspci -v -s 00:01.0 | grep -Po '^\s*\K\S+(?=\s+VGA\s)'
^\s* совпадает с нулевым или большим пробелом в начале и \K отбрасывает совпадение, это необходимо для решения второго случая, когда пробелы в начале \S+ соответствуют любому количеству символов без пробелов, это наша желаемая часть. Положительный шаблон с нулевой шириной, (?=\s+VGA\s), гарантирует, что желаемое совпадение выдается VGA после пробелов после желаемой части. Чтобы сохранить вывод в переменной, используйте команду substitution ($()):
value=$(lspci | grep -Po '^\s*\K\S+(?=\s+VGA\s)')
Аналогично:
value=$(lspci -v -s 00:01.0 | grep -Po '^\s*\K\S+(?=\s+VGA\s)')
Теперь вы можете получить значение с помощью $value.
Пример (в моей системе):
$ lspci | grep -Po '^\s*\K\S+(?=\s+VGA\s)'
00:02.0
$ lspci -v -s 00:02.0 | grep -Po '^\s*\K\S+(?=\s+VGA\s)'
00:02.0