
入力する:
<e1 name="file1" id="id1" anotherId="id2">
希望の出力:
file1
次のように必要なものを入手できます。
echo '<e1 name="file1" id="id1" anotherId="id2">' | sed 's/\(.*name="\)\(.*\)\(".*\)/\2/' | sed 's/".*//'
出力:file1
可能であれば、コマンドセットを改善し、sedの最後のパイプを削除したいと思います。 sedの最後のパイプを削除すると、目的の結果が得られません。
echo '<e1 name="file1" id="id1" anotherId="id2">' | sed 's/\(.*name="\)\(.*\)\(".*\)/\2/'
出力:
file1" id="id1" anotherId="id2
ご覧のとおり、sedはfile1の後の最初の引用符ではなく、最後の引用符を選択しました。
誰でもこのコマンドを改善するのに役立ちますか?
答え1
echo '<e1 name="file1" id="id1" anotherId="id2">' |
sed -n 's/.*name="\([^"]*\)".*/\1/p'
またはGNUを使用する(grep
PCREサポートで構築されている場合):
echo '<e1 name="file1" id="id1" anotherId="id2">' |
grep -Po 'name="\K[^"]*'
答え2
sed
このバージョンでは、少し簡単にすることができます。
$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
sed 's/.*name="\(.*\)" id.*/\1/'
すべてを括弧で囲む必要はありません。後で削除できるように興味のあるアイテムを保存してください。
grep
grep
Perlの正規表現エンジン(PCRE)機能を使用することもできます。
$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
grep -Po '(?<=name=")(\w+)(?=")'
これは、PCREの将来指向的および過去指向的な機能を利用します。この表記法は、次の文字シーケンスを探します。"name="
今後私たちは何を探していますか?このビットはそれをしています:
(?<=name=")
それから私たちが実際に探している一連の単語文字を見つけます。
(\w+)
前を見下ろす最後のポイントは次のとおりです。
(?=")
"
引用符()を探しています。後ろに私たちは何を探していますか?
アッ
$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
awk '{gsub("\"","");split($2,a,"="); print a[2]}'
このバリアントは、グローバル置換のために二重引用符( `` `` ``)を文字列にします。
gsub("\"","")
残りの文字列は次のようになります。
<e1 name=file1 id=id1 anotherId=id2>
したがって、awk
一般的なように分割すると、2番目の列が私たちが興味のある部分になります。それはなり$2
ますawk
。したがって、その変数を取得して等号(=
)に分割できます。
split($2,a,"=");
これにより$2
結果が分割され、配列に保存されますa
。その後、等号の右側にあるすべての項目である配列の2番目の要素を印刷できます$2
。
file1