sedを使用して変数から複数の正規表現を削除する

sedを使用して変数から複数の正規表現を削除する

私はこれが簡単だと確信していますが、良い例が見つからないようです。ボックスの初期化システムを見つけるために/ proc / 1 / exeを解析しようとしています。 Exeはinitシステムへのシンボリックリンクですが、ファイル数を数えてみるとその中に引用符がありますが、それを削除したいと思います。残念ながら、exeには通常のアポストロフィ(U + 0027)と左右の単一引用符(U + 2018とU + 2019)が表示されます。システムによって異なります。これは、私が実行しているシェルおよび/またはそのバージョンが原因であるのか、統計ユーティリティが原因であるのか、システム自体が原因であるのかは不明です。今、これら3つの文字がすべて混ざっているのを見ました(時々一緒に混在しています)。

最終的に同じsedコマンドを使用してこれらの文字をすべて削除したいと思います。これまでは、sedを他のsedコマンドに接続しなければ、これを行うことができませんでした。

完全なexeファイルは次のとおりです。

$stat /proc/1/exe

  File: '/proc/1/exe' -> '/sbin/init'
  Size: 0           Blocks: 0          IO Block: 1024   symbolic link
Device: b9h/185d    Inode: 76948360    Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-02-01 14:52:39.101744022 -0700
Modify: 2017-01-25 12:52:20.741244423 -0700
Change: 2017-01-25 12:52:20.741244423 -0700
 Birth: -

この例では一般的なアポストロフィに過ぎませんが、他の引用符も見たことがあります。だからまず必要なものを手に入れます。

$stat /proc/1/exe | grep File: | awk -F '->' '{print $2}'
'/sbin/init'

今、引用符を削除したいと思います。さまざまな種類の引用符をすべて削除する唯一の方法は、複数のsedコマンドを使用することです。

$stat /proc/1/exe | grep File: | awk -F '->' '{print $2}' | sed 's/\xe2\x80\x98//g' | sed 's/\xe2\x80\x99//g' | sed 's/\x27//g'
 /sbin/init

次に、別のawkステートメントにパイプします。

$stat /proc/1/exe | grep File: | awk -F '->' '{print $2}' | sed s'/\xe2\x80\x98//g' | sed 's/\xe2\x80\x99//g' | sed 's/\x27//g' | awk -F '/' '{print $NF}'
init

私は/proc/1/commを知っているか、/proc/1/exeでlsを使用しています。問題は、3つのsedコマンドを1つにまとめる方法です。それが必要です:

開く、閉じる、またはアポストロフィがある場合は削除します。すべての状況でこれを行う必要があります。

しかし、ボックスの初期化システムを取得するためのより良いコマンド(信頼できない/ proc / 1 / commを除く)を知っている人がいる場合、またはこれらのコマンドをより効率的にすることができる人がいる場合は、プロセスで学ぶことに興味があります。

答え1

他の人が指摘したように、PID 1の属性を決定するより良い方法があります。単一のパイプラインで複数の呼び出しを使用することはほとんど良い考えではgrepありません。そうでない場合はを使用してください。 (簡単)できない場合は、以下を使用してください。sedawkgrepsedsedawk

stat /proc/1/exe | sed -n '/File:/{s/.*-> *[\xe2\x80\x98]//;s/[\xe2\x80\x99].*//p;q}'

答え2

ここでは少し異なるアプローチを取ることができます。これは、「3つのsedコマンドを1つにまとめる方法」という元の質問をまだ満たし、コマンド自体も改善します。疑いなく、initシステムを検索する方法という2番目の問題を解決する他の方法がたくさんあります。

不要なものを削除しようとする代わりに、キャプチャグループを使用して目的のものをキャプチャし、文字セットを使用して複数の値を一致させることができます。文字セットは角かっこ「[]」で示されます。内側に一致させたい項目を正確に入力すると、その間に暗黙のORステートメントが表示されます。したがって、開始引用符と一致するようにまたは使用するアポストロフィ:

[\xe2\x80\x98 \x27]

先頭引用符は「e28098」16進数文字で、アポストロフィは「27」16進数文字です。 2つの個々の文字を強調するためにそれらの間にスペースを入れましたが、技術的にはこれは開始引用符と一致します。またはスペースまたはアポストロフィ。一致しない場合は、スペースを削除してください。正しい引用符と一致させるには、「e28099」を追加することもできます。

コマンド自体を改善し、「init」または「systemd」のみをインポートするには、キャプチャグループを使用して他のアプローチを取ることができます。キャプチャグループは角かっこ「()」で表されます。その後、そのキャプチャグループを参照できます。たとえば、必要なものをキャプチャするには、次のコマンドを使用しました。

stat /proc/1/exe | sed -rn 's/^.*File:.*->.*[\xe2\x80\x98\x27]\/.*\/(.+)[\xe2\x80\x99\x27]$/\1/p'

キャプチャグループ(角括弧の間の「.+」)は、開いた引用符またはアポストロフィと閉じた引用符またはアポストロフィの間の最後のスラッシュ以降のすべての内容をキャプチャします。これは「\1」を使用して参照されます。 Sed は行全体をキャプチャグループの内容に置き換えます。

  • -r拡張正規表現の場合(少なくとも私のバージョンのsedでは)
  • -n は印刷を抑制するために使用されます。 「/p」オプションと一緒に使用すると、パターンと一致する行のみが印刷されますが、パターンが置き換えられた後に印刷されます。これにより、sedはgrepのように動作します。

これが他の人に役立つことを願っています。

関連情報