コマンドの出力から引用文字列の内容を抽出するにはどうすればよいですか?


26

VBoxManage list vms次のような出力があります。

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

私が名前をつかむために必要archarch2し、変数に保存します。

回答:


34

grep + sedを使用する

これにより、これら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、最初の二重引用符を切り捨て、それらの間にあるものを保持し、残りの引用符とその後のすべてを切り取るために使用することができます:

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

その他の方法

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

このコマンドtrを使用して、文字を削除できます。この場合、二重引用符が削除されます。

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

grepのPCRE機能を使用すると、二重引用符で始まるか二重引用符で終わる部分文字列を検索して、部分文字列のみをレポートできます。


1
tr -d \"引用符を削除する別の方法です。(tr通常、1つの文字セットを別の文字セットに変換-dします。代わりにそれらを単に削除するように指示します。)
deltab

1
slm- /address/sedlike を追加すると、sed '/^"\(arch[^"]*\)/s//\1/その文字列を含む行のみを操作します。
mikeserv 14年

1
@mikeserv-true、アーチが彼の出力でどれだけ一貫しているかはわかりませんでした。しかし、もしそうなら、それもうまくいくでしょう。
slm

1
良い点slm。一貫性のある兆候はありません。ごめんなさい。
mikeserv 14年

2
ただし、行に二重引用符が2つしかない場合に備えsedて、実際に実行する必要があることに気付きs/^"\([^"]*\)".*/\1/ました。
mikeserv 14年

19

それは別の仕事ですcut

VBoxManage list vms | cut -d \" -f2

3
とてもきちんとした!仕組み:cut引用符を区切り文字として使用して各行をフィールドに分割し、フィールド2を出力します:フィールド1は最初の引用符の前の空の文字列、フィールド2は引用符の間の必要な文字列、フィールド3は残りの文字列ですライン。
デルタブ

7

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]}"

これは、変数を使用するようになると簡単になる場合があります。


sedコマンドを解散してください。
ハリーズカヴァン

5

bashを使用して、次のように記述します。

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

5

そして、--perl-regexpオプション付きのgrep onelinerを介して、

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

説明:

(?<=^\")[^"]*->ここでは後読みが使用されます。"二重引用符の直後(二重引用符で始まる行のみ)にある任意の文字に一致しますが、ゼロ回以上ではありません(二重引用符を見つけると、一致を停止します)。

別のUいハックsed

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

0

正規表現には欲張りモードと非欲張りモードがあるため、同じ行に複数のターゲットがある場合、希望どおりに抽出されません。ライン:

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

ターゲット:

tom
jerry

コマンド(欲張りモード):

grep -oP '".*"' name

コマンド(貪欲でないモード):

grep -oP '".*?"' name
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.