
У меня есть вывод, VBoxManage list vms
который выглядит следующим образом:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Мне нужно взять имена arch
и arch2
сохранить их в переменной.
решение1
Используем grep + sed
Это позволит проанализировать содержимое этих двух строк:
$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2
Вышеуказанный код ищет строку, соответствующую шаблону ".*"
. Это будет соответствовать всему, что находится внутри двойных кавычек. Поэтому grep
вернет следующие типы значений:
"arch"
"arch2"
Канал to sed
удалит все двойные кавычки из этих строк, давая вам строки, которые вы ищете. Нотация sed 's/"//g'
предписывает sed
выполнить поиск и замену для всех вхождений двойных кавычек, заменяя их ничем, s/"//g
. Команда s/find/replace/g
— это то, что там происходит, а завершающий g
to search говорит ей сделать это глобально для всей заданной строки.
Используя только sed
Вы также можете использовать , sed
чтобы отсечь начальную двойную кавычку, оставить то, что между ними, и отсечь оставшуюся кавычку и все, что после нее:
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
Другие методы
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
Эту команду tr
можно использовать для удаления символов. В данном случае это удаление двойных кавычек.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
Используя grep
функцию PCRE, вы можете искать любые подстроки, которые начинаются с двойной кавычки или заканчиваются двойной кавычкой, и выводить только подстроку.
решение2
Это еще одна работа для cut
:
VBoxManage list vms | cut -d \" -f2
решение3
С помощью sed
вы можете сделать:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Объяснение:
s/.../.../
- сопоставить и заменить^
- совпадение в начале строки\(...\)
- это обратная ссылка, мы можем сослаться на то, что здесь сопоставлено позже с помощью\1
[^"]*
- соответствует любой последовательности, которая не содержит a"
(т.е. до следующего"
).*
- сопоставьте остальную часть строки\1
- заменить обратной ссылкой
Или с awk
:
var=$(VBoxManage list vms | awk -F\" '{ print $2 }')
Обратите внимание, что в современных оболочках вы также можете использовать массив вместо обычной переменной. В bash
вы можете сделать:
IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"
Это может оказаться проще, когда вы начнете использовать переменную.
решение4
Используя bash, я бы написал:
while read vm value; do
case $vm in
'"arch"') arch=$value ;;
'"arch2"') arch2=$value ;;
esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2