Alıntılanan dizelerin içeriğini bir komutun çıktısından nasıl çıkarabilirim?


26

Bunun VBoxManage list vmsgibi görünen bir çıktım var :

"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}   
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}  

İsimleri kapmak gerekir archve arch2bir değişkene kaydedin.

Yanıtlar:


34

Grep + sed kullanarak

Bu, bu 2 dizenin içeriğini ayrıştırır:

$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2

Yukarıdaki, kalıpla eşleşen bir dize arar ".*". Bu, çift tırnak içinde meydana gelen herhangi bir şeyle eşleşecektir. Bu nedenle grepbu tür değerleri döndürür:

"arch"
"arch2"

Boru, sedaradığınız ipleri veren bu iplerden çift tırnak bırakacaktır. Notasyon sed 's/"//g', sedçift ​​tırnak işareti tüm oluşumlarında bir arama yapma ve değiştirme, onları hiçbir şeyle değiştirme talimatıdır s/"//g. Komut s/find/replace/gorada olup biten gve arama arayışı verilen tüm dizgede global olarak yapmasını söyler.

Sadece sed kullanarak

Ayrıca sed, başlangıçtaki çift teklifi kesmek, aralarında ne olduğunu tutmak ve kalan teklifi kesmek için kullanabilirsiniz:

$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2

Diğer yöntemler. Diğer metodlar

$ grep -o '".*"' somefile | tr -d '"'
arch
arch2

Komut trkarakterleri silmek için kullanılabilir. Bu durumda çift tırnak işareti siliyor.

$ grep -oP '(?<=").*(?=")' somefile
arch
arch2

grepPCRE özelliğini kullanarak , çift alıntı ile başlayan ya da çift alıntı ile biten herhangi bir alt dizgeyi arayabilir ve sadece alt dizgiyi rapor edebilirsiniz.


1
tr -d \"tırnak işaretleri silmek için başka bir yoldur. ( trNormalde birbiri içine karakterlerden biri dizi çevirir; -dsadece yerine silmek için söyler.)
DeltaB

1
slm - Bir eklerseniz /address/için sedgibi sed '/^"\(arch[^"]*\)/s//\1/yalnızca o dizeyi içeren hatlar üzerinde işlem edeceğiz.
mikeserv

1
@mikeserv - true, kemerin çıktısında ne kadar tutarlı olacağından emin değildi. Ama eğer öyleyse, o zaman da işe yarayacaktı.
slm

1
iyi nokta slm. Tutarlı olacağına dair hiçbir gösterge yok. Üzgünüm.
mikeserv

2
Sadece satırda sadece iki çift tırnak olması durumunda yapabileceğinizin sedgerçekten farkına vardım s/^"\([^"]*\)".*/\1/.
mikeserv

19

Bu başka bir iş için cut:

VBoxManage list vms | cut -d \" -f2

3
Çok temiz! Nasıl çalışır: cuther satırı satır işaretleyicisini ayırıcı olarak kullanarak alanlara böler, ardından alan 2'yi çıkarır: alan 1, ilk tekliften önce boş dizedir, alan 2, tırnaklar arasında istenen dizedir ve alan 3, geri kalanın kalanıdır hat.
del

7

İle sedYapabileceğiniz:

var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')

Açıklama:

  • s/.../.../ - eşleştir ve değiştir
  • ^- hattın başında maç
  • \(...\) - bu bir geri referans, burada daha sonra neyle eşleştirildiğine bakabiliriz. \1
  • [^"]*- içermeyen herhangi bir diziyi eşleştirin "(yani bir sonrakine kadar ")
  • .* - hattın geri kalanını eşleştir
  • \1 - geri referans ile değiştirin

Veya awk:

var=$(VBoxManage list vms | awk -F\" '{ print $2 }')

Modern mermilerde normal değişken yerine bir dizi de kullanabileceğinizi unutmayın. Gelen bashyapabileceğiniz:

IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"

Değişkeni kullanmaya başladığınızda bu daha kolay olabilir.


Benim için şu emirleri bozar mısın lütfen?
Harrys Kavan

5

Bash kullanarak şunu yazarım:

while read vm value; do
    case $vm in
        '"arch"') arch=$value ;;
        '"arch2"') arch2=$value ;;
    esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2

5

Ve --perl-regexpseçeneği ile grep oneliner aracılığıyla ,

VBoxManage list vms | grep -oP '(?<=^\")[^"]*'

Açıklama:

(?<=^\")[^"]*-> Burada bir gözbağı kullanılıyor. Herhangi bir karakterle eşleşir, ancak "sıfır veya daha fazla kez değil (bir çift tırnak bulduktan sonra, eşleşmeyi durdurur), çift tırnaktan hemen sonra olan (yalnızca çift tırnakla başlayan satır).

Başka bir Çirkin kesmek sed,

$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2

0

regex açgözlü ve açgözlü olmayan modlara sahip olduğundan, aynı hatta birden fazla hedefiniz varsa, istediğiniz gibi çıkarmazsınız. Hat:

"tom" is a cat, and "jerry" is a mouse. 

Hedef:

tom
jerry

Komut (açgözlü modu):

grep -oP '".*"' name

Komut (açgözlü olmayan mod):

grep -oP '".*?"' name
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.