私は最近、職場で誰かにipcs -qaの出力を取得し、スペースで区切って解析し、監視のためにデータベースに保存する方法を尋ねました。彼は私にこれを与えた:
ipcs -qa | sed 's/ [ ]* / /g'
動作しますが、なぜですか?彼はどのようにそのパターン文字列を作成しましたか?ビルド方法のドキュメントはどこにありますか?マニュアルページを確認しましたが、非常に不透明です。
答え1
sed 's/ [ ]* / /g'
\_/ | \____/ | |
| | | | \- g=globally (not just one occurrence)
| | | |
| | | \- to
| | |
| | \- from
| |
| \- s=substitute
|
\- program sed
セクションでは:
/ [ ]* /
| \_/|
| | \- repeated 0-infinite times
| |
| \- group of characters
|
\- boundary
*を含む3つの量子があります:
- 0から無限大? 0回または1回
- 1~無限大
通常、最後の文字のみを参照するため、x *はx、xxxx、および何も一致しません。 X? 0 または 1 と一致 x、x+ は x、xx、xxx などと一致しますが、[aeiou]+ または角かっこ (foo)* で囲まれた組み合わせなどの文字セットと一致できます。 1つ目はiiaiaeiと一致し、2つ目はfooとfoofooと一致します。
グループは、列挙型[aeiou]またはfrom-toグループ:[az]または組み合わせ:[0-9a-fA-F:]です。グループにマイナス記号を含めるには、末尾または先頭に入れる必要があります([-,:])。
最も一般的に使用されるコマンドはおそらく「s」です。他の「d」は削除を意味し、「p」は印刷を意味する。
パターンは区切り文字(通常はスラッシュ)で囲まれています。
sed 's/foo/bar/'
sedはライン指向です。 (最初の)fooをbarに置き換えるには、上記のコマンドを使用します。すべてを置き換えるには、グローバルに「g」が必要です。
sed 's/foo/bar/g'
sedを使用して行番号を呼び出す別の方法:
sed -n '1,5p' file
-n はデフォルトでは印刷しません。 1,5p はライン 1 からライン 5 まで印刷することを意味します。
sed '6,$d' file
これは同じです。 6行から最後まですべて削除されます。
sed '5q' file
再び同じです。 5行以降終了します。
通常、sedを使用すると、コマンドを読むよりも書くのが簡単です。
答え2
最初はすべてうまくいくようです。
sed 's/[ ]* / /g'
sed 's/ [ ]*/ /g'
sed 's/ * / /g'
sed 's/ * / /g'
sed 's/ */ /g'
sed 's/ \+/ /g'
sed 's/ \+ / /g'
デフォルトでは、この関数は2つの空白と任意の数の連続した空白を一致させるだけです。正規表現は基本的に貪欲なので、「すべての数字」は見つけることができる最大数であるために機能します。 (そして、[ ]
「次のいずれかに一致する」ならば、空白文字をリストするだけです)
スペースを扱うため、質問に使用される特定の構文が理想的です。
sed 's/ [ ]* / /g'
2つのスペース文字が隣接していないため、一目で3つのスペースがあることがわかります。