У меня есть выход, VBoxManage list vms
который выглядит так:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Мне нужно , чтобы захватить имена arch
и arch2
и сохранить их в переменную.
У меня есть выход, VBoxManage list vms
который выглядит так:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Мне нужно , чтобы захватить имена arch
и arch2
и сохранить их в переменную.
Ответы:
Это проанализирует содержимое этих двух строк:
$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2
Вышесказанное ищет строку, соответствующую шаблону ".*"
. Это будет соответствовать всему, что встречается в двойных кавычках. Так grep
что вернет эти типы значений:
"arch"
"arch2"
Канал, по которому sed
будут отбрасываться любые двойные кавычки из этих строк, дает вам строки, которые вы ищете. Запись sed 's/"//g'
инструктирует sed
сделать поиск и замену на все случаи двойных кавычек, заменяя их ни с чем, s/"//g
. Команда s/find/replace/g
- это то, что там происходит, и трейлинг g
к поиску подсказывает ей делать это глобально на всей заданной строке.
Вы также можете использовать, sed
чтобы отрубить начальную двойную кавычку, сохранить то, что находится между ними, и отрубить оставшуюся кавычку + все, что есть после:
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
Команду tr
можно использовать для удаления символов. В этом случае он удаляет двойные кавычки.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
Используя grep
функцию PCRE, вы можете искать любые подстроки, которые начинаются с двойной кавычки или заканчиваются двойной кавычкой, и сообщать только о подстроке.
/address/
в sed
лайк, sed '/^"\(arch[^"]*\)/s//\1/
вы будете работать только со строками, содержащими эту строку.
sed
действительно должны делать s/^"\([^"]*\)".*/\1/
на случай, если в строке будет только две двойные кавычки.
Это еще одна работа для cut
:
VBoxManage list vms | cut -d \" -f2
cut
разбивает каждую строку на поля, используя знак кавычки в качестве разделителя, затем выводит поле 2: поле 1 - пустая строка перед первой кавычкой, поле 2 - искомая строка между кавычками, а поле 3 - остальная часть линия.
С sed
вами можно сделать:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Объяснение:
s/.../.../
- сопоставить и заменить^
- совпадение в начале строки\(...\)
- это обратная ссылка, мы можем сослаться на то, что здесь соответствует \1
[^"]*
- сопоставить любую последовательность, которая не содержит "
(т.е. до следующей "
).*
- соответствовать остальной части линии\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]}"
Это может быть проще, когда вы используете переменную.
Используя bash, я бы написал:
while read vm value; do
case $vm in
'"arch"') arch=$value ;;
'"arch2"') arch2=$value ;;
esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2
И один через grep oneliner с --perl-regexp
опцией,
VBoxManage list vms | grep -oP '(?<=^\")[^"]*'
Объяснение:
(?<=^\")[^"]*
-> Взгляд здесь используется. Он соответствует любому символу, но не "
ноль или более раз (как только он находит двойные кавычки, он прекращает сопоставление), которые идут сразу после двойных кавычек (только строка, которая начинается с двойных кавычек).
Еще один уродливый взлом sed
,
$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2
Так как регулярные выражения имеют жадные и не жадные режимы, если у вас есть несколько целей на одной строке, он не будет извлекаться, как вы хотите. Линия:
"tom" is a cat, and "jerry" is a mouse.
Цель:
tom
jerry
Команда (жадный режим):
grep -oP '".*"' name
Команда (не жадный режим):
grep -oP '".*?"' name
tr -d \"
это еще один способ удалить цитаты. (tr
обычно переводит один набор символов в другой;-d
вместо этого говорит просто удалить их.)