sedで複数の感嘆符を使用するのはなぜですか?

sedで複数の感嘆符を使用するのはなぜですか?

POSIX sed ドキュメント説明する:

関数の前には1つ以上の「!」文字が来る可能性があります。この場合、アドレスがパターンスペースを選択しない場合は、関数を適用する必要があります。最初の「!」文字の前には、0個以上の<空白>文字が許可されます。 <空白>文字が「!」文字の後に続くことができるかどうかは指定されていません。そのアプリケーションは<空白>文字で「!」文字を尊重してはいけません。

したがって、POSIX sedを使用すると、次のことができます。

sed -e '/pattern/!d' file

これは次のように書くのと同じです。

sed -e '/pattern/!!d' file

感嘆符!!!dnまだ機能します(3つのsedバージョンを含む)。家宝ツールボックス)。感嘆符が複数ある場合は何のメリットもないと思います。

仕様でこの構文を受け入れるのはなぜですか。実際のアプリケーションでどのように役に立ちますか?


この場合、GNU sedは互換性がないようです。感嘆符を複数使用すると文句を言う。

$ sed -e '/pattern/!!d' file
sed: -e expression #1, char 11: multiple `!'s

答え1

sedAPIは非常に原始的です。これは意図的に設計されています。少なくともそれ滞在するユニークなデザイン - 当初はもともとデザインされたかどうかはわかりません。ほとんどの場合、sed実行時に出力されるスクリプトを作成します。その他のsedスクリプト確かに簡単なことだ。マクロプリプロセッサ(例えば、および/または)はしばしばsedこのように適用される。m4make

(これは非常に仮説的なユースケースです。これは解決策に合わせて設計された問題です。これがやや難しいと思われる場合は、おそらくそうです。


次の入力ファイルを検討してください。

cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower

sed単語を追加するスクリプトを作成するには- ケースそれぞれの終わりまで適切上記の入力ファイルの1行に単語が見つかる場合にのみ適切な背景私たちはできるだけ効率的にしたい(これが私たちの目標でなければなりません(例:コンパイル作業中)。)/もしそうなら、正規表現をできるだけ適用しないでください。/

私たちができることの1つは、システム上でファイルを即座に事前編集し、コンパイル中にsedまったく呼び出さないことです。ただし、ローカル設定および/またはコンパイル時間オプションによっては、ファイルにこれらの単語が含まれているか含まれてはならない場合は、これを行うのは理想的なオプションではありません。

私たちができるもう一つのことは、ファイルを処理することです。正規表現に反対します。行番号に基づいて編集できるスクリプトを生成してコンパイルに含めることができます。sedこれは長期的により効率的な経路であることがよくあります。

たとえば、

n=$(printf '\\\n\t')
grep -En 'camel|upper|lower' <infile |
sed "   1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
        s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
        s/ *cat/!/g;s/ *dog/!/g
        s| *\([cul][^ ]*\).*|s/.*/\1-case/p|'

sed...次のスクリプトで出力を作成します...

#!/usr/heirloom/bin/posix2001/sed -nf
:1
    1!n;1!b1
    1s/.*/camel-case/p
:2
    2!n;2!b2
    2!!s/.*/camel-case/p
:5
    5!n;5!b5
    5s/.*/upper-case/p
:6
    6!n;6!b6
    6s/.*/lower-case/p
q

./bang.sedこの出力がマイコンピュータの実行可能テキストファイルであるrunに保存されている場合、./bang.sed ./infile出力は次のようになります。

camel-case
upper-case
lower-case

今私に聞くことができます...なぜこれを行うべきですか?ただgrepゲームをストリーミングしてはいけませんか?とにかくラクダケースを使う人は誰ですか?各質問に対してのみ答えることができます。全然知らない…私はそうしません。私は個人的にこの質問を読む前に全く気づいていませんでした。たくさん - !仕様の要件を解析するのは非常にきれいなキャプチャだと思います。

これたくさん - !ものしたしかし、それは私にすぐに意味があります。ほとんどのsed仕様は単純な解析と単純な作成済み sedスクリプト。この場合、必須の\newline区切り文字がより適切であることがわかり[wr:bt{]、このアイデアを念頭に置いていると、仕様の他の側面をよりよく理解することができます。(例::どのアドレスも許可せず、q1つ以上のアドレスも許可しない)

上記の例では、私はsed次のようなスクリプト形式を書いています。一度一度読んでください。詳しくは、sed編集ファイルを読み取ると、1つのコマンドブロックから次のコマンドブロックに進むことがわかります。編集ファイルが完全に完了するまで、編集スクリプトを分岐または完了しません。

私の考えではたくさん - !住所は他の場合よりもこの場合より便利ですが、正直なところ、これをうまく利用できる場合は一度も思い出せませんsed。私はまた、GNU / BSDが指定された方法でそれを処理しないことに注意する価値があると思いますsed。これはおそらく仕様であまり要求されていないので、実装がそれを無視すると非常に深刻な疑いがあります。昆虫@その結果、箱が深刻に損傷する可能性があります。

つまり、問題は規定どおりに処理されませんでした。はいコンプライアンスのように偽装する実装にはバグがある可能性があるため、ここで関連開発者に電子メールを送信するのが妥当であると考え、そうでない場合はそうする予定です。

関連情報