У мене є результат, 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
каже йому просто видалити їх замість цього.)