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