退屈な1行sed計算機

退屈なマニュアルを書くことは、私が信じていたように、キャラクターの倉庫にマイナスの影響を与えます。したがって、時々私の体はできる限り規律に抵抗します。 だから最近、ゾシュチェンコが聞いた話に感銘を受けて、私はそのスタイル、そして最も重要なことには、私に非常に近い精神を伝えようと決めました。それは本質の価値を損なうことなく、触媒として働き、鑑定家を保証しますインテリジェンスの存在。 私はそれに応じて主題を変えました、そして、それは私がそれから得たものです。



一部の支持者によると、セドは予測不能で、泥だらけの旧約聖書の構文、キリルとメトディウス自身がフィールドを編集した言語を使用しています。 私は常に相手の意見を尊重しますが、絶対にそれらを分離する必要はありません。したがって、sedは、通常のリテラル以外のsedコードの行に神秘的なキャラクターが表示されるときに、トウモロコシをすばやく満たすために必要なものであり、議論の中で黒い羊ではないことを自分で決めました式。



どんなツールがありますか? 1つ目はbash(バージョン4.3.42)です。 2番目はsed(4.2.2)です。 バージョンから判断すると、少し空想した場合、私たちの馬はほぼ同じ時代に始まり、頭と頭ではなく、体の半分以下の違いで行くと仮定できます。 これらはすべて、コンピューターのオペレーティングシステムfedora 24にあります。



記憶をリフレッシュし、emulekのチュートリアルのトップを実行すると、sedにはシェルコマンドを埋め込み、テンプレートをこのコマンドで返された値に置き換えることができる修飾子があることがわかりました。 この分野の私の最初の行は非常に励みになりました。



sed -r 's/([0-9]+)([-+])([0-9]+)/expr \1 \2 \3/e' <<<"2+2"
      
      





すべてが判明し、出口でソリッド4が待っていました! 「 s 」(置換)コマンドは、パターン/([0-9] +)([-+])([0-9] +)/で一致を検索し、コマンドの出力/ expr([0-9] +)に置き換えます([-+])([0-9] +)/ e このコマンドのパラメーターは、テンプレートで定義されています。 カッコ内の最初のブロックは、 \ 1 second \ 2およびthird \ 3に対応します。 先に進み、算術記号「 *%/ 」を追加して機能を拡張しましょう。



 sed -r 's/([0-9]+)([-+*%/])([0-9]+)/expr \1 \2 \3/e' <<<"2*2"
      
      





そしてすぐに、出力の「 expr 」コマンドで構文エラーを取得します。 置換時の式\ 2で、アスタリスクは特別な意味を持ち、sedはその値を独自の値、つまりvoidに置き換えることを分析し、理解し始めます。 Bashovチームがこのシンボルを配布する前に、このシンボルをシールドする必要があります。 もう1つの置換コマンドを作成し、テンプレートを少し変更します。



 sed -r 's/\*/\\\*/; s/([0-9]+)([-+*%/\]+)([0-9]+)/expr \1 \2 \3/e' <<<"2*2"
      
      





再び4! 傑作は「再びデュース」という絵を求めます! ここで、別の置換コマンドを導入しました。 最初のテンプレートのアスタリスクの前にバックスラッシュアイコンを付けて悪役のスーパーアビリティを奪い、交換可能な行ではバックスラッシュアイコン自体をエスケープすることを忘れないでください。 その結果、この部分はひどい外観/ \\\ * /に成長します。



また、2番目のテンプレート(2番目の括弧)にバックスラッシュが追加され、角括弧[-+ *%/ \]で定義された文字クラスに庭をフェンスしないように、2行のパターンマッチングを与える量指定子 " + "を使用します文字「 \ * 」。 テンプレートをより正確に決定することは確かに可能でしたが、これに関しては十分です。



Bashは、利用可能なほとんどすべてのことをいくつかの異なる方法で実行できるという点で優れています。 ところで、これは彼の明らかな混乱です。 整数で算術演算を実行するために、より現代的な表記法が提供され、ひげを生やした管理者に対する攻撃はありません。 新しい設計により、コードの一部を取り除き、プログラムを徹底的に簡素化できます。 スプロケットを保護する必要はありません。 コードを簡素化するため、追加の機能を導入して、初心者にとって許容できるレベルで複雑さのレベルを維持することもできます。



エディターに1行だけを送信すると、プログラムはこの作業を停止しました。 Sedは、条件付きジャンプと無条件ジャンプの可能性を提供します。 アセンブラに精通している人は、ジャンプまたはラベルジャンプの完全な類似性をすぐに発見できます。 原理は同じです。 エディターでの作業が作業のように見え始めているため、これはすでに興味深いものになっています。

このプログラムで。



htmlはマークアップ言語であるという定評がありますが、これに同意します。 したがって、トランジションといくつかの組み込み関数がなければ、sedエディター言語もこの定義に組み込むことができると思います。 ただし、エディターにはトランジションと機能があります。つまり、テキストを使用して作業のプログラミングを完全に行うことができます。



移行の導入を伴うプログラムの次のリリースは、このコードの形になります。



 sed -r ':again s/([0-9]+)([-+%/*])([0-9]+)/echo $((\1 \2 \3))/e; t again'
      
      





ターミナルでこのようなコードを実行することにより、2つの数値を使用して算術式を入力し 、「 Enter 」を押すだけで済みます。 「 もう一度 」ラベルは、サイクルの開始と終了をすぐに示します。 ラベル「 again 」の条件付きジャンプコマンド「 t 」は、コロンの後にこのラベルで定義された次のサイクルの先頭に戻り、エディターは次の行が入力されるのを待ちます。



プログラムを終了することは、 Ctrl + Cキーの組み合わせを押すことでトリガーされるよく知られた割り込み信号であることに注意してください。



しかし、条件分岐の作業を見てみましょう。 「 t 」コマンドは「 s 」(置換)コマンドとともに使用され、後者の結果は遷移が実行されるかどうかです。 最初の(複数ある場合)コマンド " s "がバッファー内で置換を行う場合、条件付きジャンプが実行されます。



最初の(複数ある場合)コマンド " s "が失敗した場合に実行される " T "コマンドもあります。



条件による遷移を使用してプログラムを逆アセンブルしました。 やめて そして、無条件の遷移で十分な場合に、条件ごとの遷移が必要なのはなぜですか。 「 t 」コマンドを無条件ジャンプコマンド「 b 」に置き換えましょう。 テスト中です。



 sed -r ':again s/([0-9]+)([-+%/*])([0-9]+)/echo $((\1 \2 \3))/e; b again'
      
      





データを入力する必要がありますが、出力には結果がありません! ロジックによってすべてが同じように機能するはずなので、どこが間違っているのでしょうか? 戻ってプログラムを分析しましょう。 いつものように、すべてが初歩的であることが判明しました。 しばらく考慮しなかったため、条件分岐コマンド「 t 」がトリガーされ、コマンド「 s 」に置換がある場合にプログラムの実行がラベルに変換されます。



どうやら、拡張子「 e 」のデザインは少し異なって動作します。 思いがけないことに、私たちの場合、置換はありません。私たちの行は、テンプレートと完全に一致しており、bashユーティリティのパラメーターの形で変更されていないように見えます。 そして、ここでは、ほとんどの場合、代替の秘跡が起こりますが、残念ながら、私たちの編集者は、「 s 」チームはこれとは関係がないと考えていますが、拡張コマンド「 e 」が関与しています。 また、ラベルがない場合や遷移条件が満たされていない場合、プログラムの実行はラベルの先頭までではなく、コマンドラインの末尾に移動することがわかっているためです。 コードを修復します。



 sed -rn ':again s/([0-9]+)([-+%/*])([0-9]+)/echo $((\1 \2 \3))/e;p;d; b again'
      
      





この状況には説明が必要です。 さらに、状況を修正するために、さらに2つのコマンドと1つのオプションを導入します。 「 p 」コマンドで計算結果を記録した後、バッファーの内容を強制的に出力し、プログラムの先頭に戻る前に、「 d 」コマンドでそれをクリアします。 「 -n 」オプションは通常、「 p 」コマンドと連携して機能し、バッファーの自動印刷を抑制します。 私は数年間そのような不幸な出来事の後に成熟したと感じています、そして、これが続くならば、私はすぐに年をとり、古いメイドのままです。 こんなにつまらないとは思いもしませんでした!



私たちのプログラムは再び動作しますが、それでも大部分は冗長です。 たとえば、sedの機能を実証するために私が導入したラベルと、予想外に探偵コショウを追加したラベルは不要です。 セミコロンで区切られた行に複数のコマンドがあり、ラベルによってコマンドまたはコマンドブロックの1つをバイパスできる場合、それらは理にかなっています。 このような難易度で、マスターされたベルとホイッスルをロールバックする必要があります。 実際、エディターはすでに次の行が入力されるのを待っており、ラベルがあった最初から入力を開始します。 損傷なしで、次のように行を書き換えることができます。



 sed -r 's/([0-9]+)([-+%/*])([0-9]+)/echo $((\1 \2 \3))/e' -
      
      





またはこのように:



 sed -r 's/([0-9]+)([-+%/*])([0-9]+)/echo $((\1 \2 \3))/e'
      
      





以前に手動モードでモデル化したこのメインサイクルは、既にエディタープログラムに組み込まれており、今後も引き続き使用します。 機能に戻りましょう。 この計算機の作業を思い出すと、中間結果を保存するための追加のバッファーが見つかります。 しかし、sedはどうですか? sedには、追加のバッファーと、それを操作するためのいくつかのコマンドもあります。 これが行う前に行ったことは、ラインがロードされ、アクションが実行されるメインバッファーで作業することでした。 追加のバッファーを使用して計算の結果を保存し、さらに、算術アクションの符号と第2オペランドを行に入力するだけで、計算の中間結果で後続の操作を実行できる場合に機能を追加します。 また、負の数で作業を提供します。 また、bash自体の機能を削減せず、「退屈ではない」計算機のアルゴリズムに少しエントロピーを追加せず、数値の累乗を増やします。 bashでは、べき乗はNUMBER ** DEGREEのように見えることを思い出させてください。 記号は明確で、二重アスタリスクが記載されています。 同時に、私が理解できる限りのすべての最適化をすぐに実行します。



最初は、コードの開発を探している盲目の子猫のように鼻を突いていましたが、結論として次のフォームを取得しました。



 sed -r '/^[-+/%*]\*?-?[0-9]+$/{x;G;s/\n//}; s/.*/echo $((&))/e;h'
      
      





本格的なテンプレートを定義することは不必要な無駄であると考えましたが、これは本質的にこのデザインでシェルコマンドを入力する機会を提供するだけで、テンプレートを最小限の/.*/に減らしました。 これは許容範囲内であり、タイピングエラーから100万ドルの保険がかけられているとさえ想像していました。 ここにそのようなパターンを挿入できるほど自信がない場合は、 s / ^-?[0-9] + [-+%/ *] \ *?-?[0-9] + $ / 。 入力エラーがあったとしても、中間結果が失われると追加のバッファーが更新され、サイクルは非常に単純に「やり直し」と呼ばれるため、気にしないように見えるブロンドに他の人にアドバイスします。 プログラムを再起動する必要はまったくなく、正しいデータの入力を開始するだけです。







それでは、コードの最後の行に何を詰め込んだかを見て、プログラムのアルゴリズムから始めましょう。 エディターを開始すると、エディターは入力のスタンバイモードになります。 入力する最初の行は、2つのオペランドと中央の算術記号で構成されています。 プログラムコードの最初に、2つのオペランドで構成されるすべての操作に「気付かない」テンプレートがあります。つまり、このフィルターは最初の行をスキップし、アクションはすぐにシェルユーティリティを呼び出す既知のコマンドに移動して最終結果を取得します。



プログラムのこの部分では、テンプレートを単純化しただけでなく、オペランドを記述するための式も単純化しました。 ここで、オペランドを個別に挿入するのではなく、 &で示される1行のデータブロックとして挿入します。 アンパサンド、文字列全体を示すこの文字の同義語は\ 0です。 セミコロンで終わるこのコードブロックでは、メインバッファーの値をシェルコマンドによって計算された値に変更します。 セミコロンの後に、メインバッファーにあるすべてのものを追加のバッファーにコピーするコマンド " h "があります。 その後、プログラムはメインバッファーの内容を表示し、新しい行に入ることを期待してループの先頭に移動します。



これで、バッファに第1オペランドがあり、算術アクションの符号と第2オペランドのみを入力することがわかりました。 最初のsコマンドは、メインバッファーにパターン/ ^ [-+ /%*] \ *?-?[0-9] + $ /に一致する行があることを検出しその後、アクションは中括弧で囲まれたコマンドのブロックに渡されます。 ブロック内の2番目のコマンドは「 G 」で、メインバッファーの末尾に改行文字「 \ n 」を追加し、追加バッファーから行をコピーした後です。 そのため、メインバッファーには、改行文字で区切られた2行が同時にあります。 1つ目は、入力された演算記号と2つ目のオペランドです。



すぐに注目に値するのは、オペランドの不適切な配置です。 追加のバッファからメインバッファに行を追加する前にこの小さな誤解を修正するには、「 x 」コマンドの形式でニーを使用します。これにより、メインバッファが追加のバッファと交換され、「 G 」コマンドが実行された後、すべてが正しい順序になります。 その結果、2つの「 x; G 」コマンドを実行した後、メインバッファーに同様の行1オペランド \ n SIGN 2オペランドがあります。 式の途中の改行は冗長です。 s / \ n //を置き換える次のコマンドで削除します。 さて、それから何が書かれているか、制御は「計算機」に行きます。



以前にsedストリームエディタに慣れていなかった人は、emulekからチュートリアルを個別にめくって、sedで実際にバッファが何と呼ばれているかを見ることができます。また、他にも便利なものがたくさんあります。



デザートについては、すべてのhomeSEDに、そのようなスーパーシードユーティリティが自然界に存在することを通知します。 リポジトリでは、debian-testingはssedパッケージと呼ばれます。 これは、Perlの正規表現を理解できるストリームエディターです。 Fedora 24のrpmfusionリポジトリにはこのユーティリティがありません。 しかし、これはまったく異なる退屈な話です。



All Articles