次のようなVBoxManage list vms
からの出力があります。
"Arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"Arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Arch
とArch2
という名前を取得して、変数に保存する必要があります。
これにより、これら2つの文字列の内容が解析されます。
$ 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機能を使用すると、二重引用符で始まるか二重引用符で終わるすべての部分文字列を検索して、部分文字列のみを報告できます。
これはcut
の別の仕事です。
VBoxManage list vms | cut -d \" -f2
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]}"
_
これは、変数を使用するときに簡単になります。
そして、--Perl-regexp
オプション付きのgrep onelinerを使用したもの、
VBoxManage list vms | grep -oP '(?<=^\")[^"]*'
説明:
(?<=^\")[^"]*
->後読みがここで使用されています。二重引用符(二重引用符で始まる行のみ)の直後にある任意の文字に一致しますが、"
のゼロ回以上一致しません(二重引用符が見つかると一致しなくなります)。
sed
によるもう1つの醜いハック
$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
Arch
arch2
Bashを使用して、次のように記述します。
while read vm value; do
case $vm in
'"Arch"') Arch=$value ;;
'"Arch2"') Arch2=$value ;;
esac
done < <( VBoxManage list vms )
echo $Arch
echo $Arch2
regexには貪欲モードと非貪欲モードがあるため、同じ行に複数のターゲットがある場合、希望どおりに抽出されません。ライン:
"tom" is a cat, and "jerry" is a mouse.
目標:
tom
jerry
コマンド(貪欲モード):
grep -oP '".*"' name
コマンド(非貪欲モード):
grep -oP '".*?"' name