IPv6アドレスを抽出するsedコマンドはどのように機能しますか?

IPv6アドレスを抽出するsedコマンドはどのように機能しますか?

IPv6アドレスを抽出するように指示された。

/usr/bin/ip a | grep inet6 | grep -vE 'fe80|host' | sed -e 's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'

sed交換品を分解するのに役立つ人はいますか?

sed コマンドは使用できません;t;d

ベストアンサー1

何かを学びたいと思いますが、よろしくお願いします。 Symcbeansedこのコマンドについて説明しますが、コードで学ぶことができるいくつかの点を追加したいと思いました。悪い習慣を避ける方法を学ぶことができます。 (-;

  1. 完全なコマンドは 2 つの s と 1 つを介してパイプさgrepれ、sedこれはほとんど常に意味がありません。あなたはsedできます住所行だけを置き換えるgrepのと同じ機能を動的に実行する正規表現を接頭辞で付けて、行を置き換えます。したがって、 '/inet6/!d'は()なしですべての行を削除でき、2行目を(または拡張正規表現オプション:)に置き換えることができます。sed -n '/foo/s/pattern/replace/p'foo!inet6grep/fe80/d;/host/d-E/fe08|host/d
  2. -eコマンドが1つしかない場合(または複数のコマンドが接続されている場合)、オプションです;。余分な部分を削除すると、コンテンツを読みやすくなります。
  3. すでに指摘したように正規表現を^.*。貪欲な人々は*どうせ最初から何でも似合うから不要なアンカーで読者の注意を気を散らさないでください。
  4. .*$最後にも同じです。アンカーを削除します。
  5. パターンにスラッシュが含まれている場合は、sコマンドに別の区切り文字を使用します。ほとんどすべての文字が許可されていますが、なぜバックスラッシュを埋めて式を読みにくくするのですか?下線は良い選択です。たとえば、次のようになります。s_.*inet6 \([^ ]*\)/.*_\1_
  6. \(…\)andを使用すると\1便利ですが、中間部分のみを抽出する場合は、開始と終了を別々に削除する方がより包括的です。s/.*inet6 //;s_/.*__
  7. 定義によると、sedコマンドの後にはオプションでジャンプマークが続きますが、この場合はそうですt;d一般的ではありませんが、法的です。 GNUバージョンでは、sedジャンプタグにセミコロンを許可しませんが、それをコマンドセミコロンとして解釈します。この場合、「代替が行われるとスクリプトの最後にジャンプ」という意味のジャンプマーカーはありません。しかし、他のsedバージョンではエラーが発生します。これらの詳細と互換性のないスクリプトがあることは本当に面倒です!たとえば、別のスクリプトを使用すると、この問題を回避できます-e '…;t' -e d。または、新しい行にコマンドを作成するだけです。
  8. t;dこの場合、置換が失敗した場合に出力が複雑になるのを防ぐのがアイデアです。良い考えですが、これを達成するための実際のツールがあります。次のコマンドpのフラグですss_.*inet6 \([^ ]*\)/.*_\1_p;d交換した場合は、pバッファをフラッシュします。読みやすく持ち運びが簡単です。
  9. 後続dのコマンドは、デフォルトの出力を抑制するオプションに置き換えることができますが、-nこれは好みの問題です。

最後に、コマンドを比較することができます

/usr/bin/ip a | grep inet6 | grep -vE 'fe80|host' | sed -e 's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'

/usr/bin/ip a | sed '/inet6/!d; /fe80/d; /host/d; s/.*inet6 //; s_/.*__p; d'

または-n代わりにEREを使用してくださいd

/usr/bin/ip a | sed -En '/inet6/!d; /fe80|host/d ;s/.*inet6 //; s_/.*__p'

ゴルファーが書くことができるコード

sed -En '/fe80|host/!s_.*inet6 ([^ ]*)/.*$_\1_p'

しかし、これは私にとって読みやすいようではありません。

おすすめ記事