`sed expr1 | sed expr2`が`sed -e expr1 -e expr2`と異なる理由

`sed expr1 | sed expr2`が`sed -e expr1 -e expr2`と異なる理由

idユーザーが属するグループのより読みやすいリストを1行ずつ提供するために出力を分離しました。

id roaima | sed 's/,/\n\t/g'
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima)
    24(cdrom)
    25(floppy)
    ...
    822413650 (international (uk) location)

グループ番号と名前をかっこで区切りたいので、このように表現を拡張しました。

id roaima | sed -e 's/,/\n\t/g' -e '2,$s/(/ (/'

しかし、最初に予想したように進行しませんでした。 2番目の表現は効果がないようです。

代わりに、目的の結果を得るには、次の2sedつの個別のコマンドを実行する必要があります。

id roaima | sed -e 's/,/\n\t/g' | sed '2,$s/(/ (/'
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima)
    24 (cdrom)
    25 (floppy)
    ...
    822413650 (international (uk) location)

sed複数のガイドラインを含む1つのコマンドの代わりに1つのパイプラインに2つのコマンドが必要なのはなぜですか?それとも1つでこれを行うことができる場合はsedどうすればよいですか?

各項目のUID / GID値と角かっこ内の名前(最初の行のUIDとGIDを含む)の間にスペースが必要ですが、実際のデータではグループ名に括弧が含まれている可能性があります。名前自体がめちゃくちゃになりたくありません。

答え1

sedawk、 or or とcut同様に、各行perl -neで1行ずつ個別に動作します。

sed -e code1 -e code2

実際には、次のように実行されます。

while(patternspace = getline()) {
  linenumber++
  code1
  code2
} continue {print patternspace}

あなたのcode2が2,$ s/foo/bar/次のような場合です。

if (linenumber >= 2) sub(/foo/, "bar", patternspace)

入力した内容は1行なのでsub()実行されません。

パターンスペースに改行文字を挿入しても増加しcode1ません。linenumber

代わりに、処理時に複数行を含むパターンスペースがあります。最初そして入力は1行だけです。複数行パターン空間の2行目以上を変更するには、次の手順を実行する必要があります。

s/\(\n[^(]*\)(/\1 (/g

もちろん、ここでは両方の操作を同時に実行できます。

id | sed 's/,\([^(]*\)(/\n\t\1 (/g'

答え2

GNU sedがある場合は、次のものを使用できます。

id username | sed 's/(/ (/4g; s/,/\n\t/g'

4番目とそれ以降の開かれている括弧の前にスペースを追加してからカンマを置き換えます。

答え3

@stéphane-chazelasが言ったことは本当ですが、いつでもスペースを最初に追加してから、次のように行を分割できます。

sed -e 's:\([,=][0-9]*\):\1 :g' -e 's:,:\n\t:g'

または単一のsedスクリプトで(なし-e):

sed 's:\([,=][0-9]*\):\1 :g; s:,:\n\t:g'

通常、 ""をコマンド検索の区切り文字として使用します/が、すべての文字も受け入れるため、 ""などの組み合わせを:避けるために、 " /\"などの別の文字を使用して読むのが簡単です。

関連情報