Как извлечь содержимое строк в кавычках из вывода команды?

Как извлечь содержимое строк в кавычках из вывода команды?

У меня есть вывод, 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— это то, что там происходит, а завершающий gto 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

Связанный контент