sedで予約されたスペースに保存されている単語を検索するには?

sedで予約されたスペースに保存されている単語を検索するには?

これはsed具体的な質問です。他のツールを使用してこれを行うことができることはよく知っていますが、知識を拡張したいと思いますsed

sedスクリプトで指定されていない単語にグローバル引用符(実際には逆引用符)をどのように使用できますか?単語は予約済みスペースに保存されます。

私が望むのはこれです:

s/word/`&`/g

しかし、秘密は、wordsedスクリプトではなく予約されたスペースに含めることです。したがって、次のように見えます。

H
g
s/^\(.*\)\n\(.*\)\1\(.*\)$/\2`\1`\3/

これは参考になります。一つ予約済みスペースで予約語が発生します。引用したいみんなgただし、静的正規表現の代わりに逆参照を使用するため、フラグを追加することはできません。

H
g
s/^\(.*\)\n\(.*\)\1\(.*\)\1\(.*\)$/\2`\1`\3`\1`\4/

これは単語の2つの発生を処理しますが、一度失敗し、複数の発生は無視されます。

私は次のようにきれいでシンプルなものを使用できると思いました。

s//`&`/g

しかし、これは最後に使用したものを再利用します正規表現、一致するものではありません。 (これは言葉になる。)

sed私が望むことをする方法はありますか? (事実は私です会議でこれがどれほど簡単かを知りたいのですが、perlまだでこれを行う方法を知りたいですsed。 )


修正する

そうではありません必要しかし、私はこの質問をするとき、私が正確に何をしていたのかについての背景知識をもう少し提供しなければならないと思いました。

大容量の文書テキストファイルがあり、その一部を圧縮してテーブルにまとめる必要がありますasciidoc。これはDescription:行などによって非常に簡単なので、実際にすべての解析を実行するクイックPrototype:スクリプトを作成しました。うまくいきますが、欠けているのは、その行にリストされているパラメータと一致する行の単語を逆引用符で表示したいことsedです。プロトタイプラインは次のとおりです。DescriptionPrototype

Prototype: some_words_here(and, arg, list,here)

私が出力するテーブルには200を超える項目があります(ソース文書にはこれよりはるかに多くのテキストが含まれています)、各引数リストには一致する単語を引用するためにバックティックのみが必要です。一つワイヤー。もっと難しいのは、いくつかのパラメータが説明行になく、いくつかのパラメータが複数回表示され、いくつかのパラメータリストが空であることです()。

しかし、時にはargが一致する可能性があることを考慮してください。部分単語名とバックティックが欲しくない場合によっては、arg名が一般的な単語(例from:)であり、関数の使用を説明する文脈で使用するときにバックティック(自動)が必要です。解決策は実際にはまったく合っておらず、代わりにvimいくつかのトリッキーなマクロの助けを借りて半分の手作業を行いました。 :)

ベストアンサー1

それは難しいことです。あなたがこれを持っているとしましょうfile

$ cat file
word
line with a word and words and wording wordy words.

どこ:

  • 行1:予約済みスペースに保存して参照する必要がある検索パターン`word`
  • 2行目:グローバル検索と置換のための行。

注文するsed

sed -n '1h; 2{x;G;:l;s/^\([^\n]\+\)\n\(.*[^`]\)\1\([^`]\)/\1\n\2`\1`\3/;tl;p}' file

説明する:

  • 1h;最初の行を予約済みスペースに保存します(これは私たちが検索したい待機です)。
    • 宿泊スペースには以下が含まれます:word
  • 2{...}2行目に適用されます。
  • x;パターンスペースを変更してスペースを維持します。
  • G;予約済みスペースをパターンスペースに追加します。パターン空間には以下があります。
word # I will call this line the "pattern line" from now on
line with a word and words and wording wordy words.
  • :l;l後で使用できるように、ポイントという名前のラベルを設定してください。
  • s///上記のパターン空間で実際の検索/置換を実行します。
    • ^\([^\n]\+\)\n^行の先頭から[^\n](1回以上\+)改行文字まで始めて、改行文字以外のすべての文字の「パターン行」を検索します\n。これで逆参照に保存されました\1。これには「パターンライン」が含まれています。
    • (.*[^`]).*後ろに文字(バックティックではない)が続くすべての文字を検索します[^`]。これはに保存されます\2。これで、\2次のものが含まれます。line with a word and words and wording wordyword
    • \1は次の検索語(逆参照\1word)なので、「パターンライン」に含まれる内容です。
    • ([^`])参照に保存されている逆引用符以外の文字が続きます\3。この操作(および上記の部分)を実行しないと、同じ->を参照し続ける\2無限ループに陥ります。なぜなら、常に成功して再びジャンプするからです(下記参照)。word````word````s///tl;:ltl;
    • \1\n\2\1\3上記の内容はすべて逆参照に置き換えられます。 2番目は\1私たちが引用すべき内容です(最初の引用は「パターンライン」です)。
  • tl;成功したらs///(何かを置き換える)名前付きタグにジャンプしてl検索し、置き換えるコンテンツがなくなるまで再起動します。これは、その単語がすべて置換/引用される場合です。
  • p;すべてのジョブが完了したら、変更された行(パターンスペース)を印刷します。

出力:

$ sed -n '1h; 2{x;G;:l;s/^\([^\n]\+\)\n\(.*[^`]\)\1\([^`]\)/\1\n\2`\1`\3/;tl;p}' file
word
line with a `word` and `word`s and `word`ing `word`y `word`s.

おすすめ記事