重複フィールドを持つ行を削除する sed 式の説明

重複フィールドを持つ行を削除する sed 式の説明

私は再帰を使わずにBashで数値セットのすべての非反復置換を生成する方法を研究していますが、この答えがうまくいくことを知っていますが、その理由を知りたいです。

1、2、3という3つの数字があるとしましょう。

次のコマンドは、すべての可能な非反復置換を生成します。

printf "%s\n" {1,2,3}{1,2,3}{1,2,3} | sort -u | sed '/\(.\).*\1/d'
123
132
213
231
312
321

引数が集合{1、2、3}中括弧が3回拡張された場合(すべての可能な結果が印刷された場合)、withが何をするのかをprintf理解します。%s

私はこれがsort -u一意の行だけを出力することを知っています。

sed /<pattern>/d一致する行を削除するために使用されることを知っています<pattern>

私はその中のパターンを読むとsed少し混乱しました。私は読み方を知っていますが、このパターンがコマンドでどのように機能するかregexわかりません。sed

\( = literal '('
.  = any character, once
\) = literal ')'
.* = any character, zero or more times
\1 = reference to first captured group

もしそうなら、このコマンドはsedこのパターンから一意でない値をどのように削除しますかregex?実際には、キャプチャされたグループはありませんが、キャプチャされたグループをどのように参照できるかはわかりません。リテラルマッチングのためにパターンに括弧を使用しますか?この実行に関するすべては、コマンドが出るまで私に意味がありましたsed

ベストアンサー1

デフォルトでは、これはsedのデフォルトの正規表現(BRE)なので、\(.\)任意の1文字を含むキャプチャグループです。その後、.*すべてをスキップし、\1グループが一致するものと一致します。すべてを一致させることができる場合、文字はグループに対して1回、逆参照に対して1回、2回表示されます。

実際、私が間違っていない限り、これは(何らかの理由で)逆参照をサポートしていないため、標準の拡張正規表現では機能しません。逆参照は以下でのみ言及されます。「BREは複数の文字と一致します。」、EREの下ではなく、実際にEREと同じ機能が私のmacOSでは動作しません(\1リテラル数の場合と同じです1)。

$ printf "%s\n" 122 321 | sed -E -e '/(.).*\1/d'
122

ただし、GNUツールはEREでの逆参照をサポートしています。

sort -uここでは必ずしも必要ではないと思います。中括弧拡張の組み合わせは、重複せずにすべての組み合わせを生成する必要があります。)

おすすめ記事