スラッシュを含む文字列をsedに置き換える方法は?


147

ローカルで開発されたVisual Studioプロジェクトがあります。コードファイルはリモートサーバーに展開する必要があります。唯一の問題は、ハードコードされたURLが含まれていることです。

プロジェクトに?page = oneなどのURLが含まれています。リンクがサーバー上で有効であるためには、/ page / oneでなければなりません。

展開前にコードファイルのすべてのURLをsedに置き換えることにしましたが、スラッシュのままです。

私はこれがかなりの解決策ではないことを知っていますが、それは私に多くの時間を節約するのは簡単です。置換する必要がある文字列の総数は10未満です。チェックする必要があるファイルの総数は約30です。

私の状況を説明する例は以下の通りです:

私が使用しているコマンド:

sed -f replace.txt < a.txt > b.txt

すべての文字列を含むreplace.txt:

s/?page=one&/pageone/g
s/?page=two&/pagetwo/g
s/?page=three&/pagethree/g

a.txt:

?page=one&
?page=two&
?page=three&

sedコマンドを実行した後のb.txtの内容:

pageone
pagetwo
pagethree

b.txtに含めるもの:

/page/one
/page/two
/page/three


回答:


274

最も簡単な方法は、検索/置換行で別の区切り文字を使用することです。例:

s:?page=one&:pageone:g

どちらの文字列の一部でもない任意の文字を区切り文字として使用できます。または、バックスラッシュでエスケープすることもできます。

s/\//foo/

どの置き換えます/foo。置換文字列で発生する可能性のある文字がわからない場合(たとえば、シェル変数の場合)は、エスケープされたバックスラッシュを使用します。


1
>または、バックスラッシュでエスケープすることもできます。別の文字列を選択できるようにするために、文字列内の文字が常にわからない場合があるので、その例はより便利です。たとえば、これ:echo / | sed s / \ // a / gが機能しません:sed:-e expression#1、char 5: `s 'のオプションが不明
Max Waterman

1
次に追加できますか?ありがとう:)二重引用符で囲まれた部分が機能しているようです:echo / | sed "s / \ // a / g"
Max Waterman

@MaxWaterman sed正規表現コマンドを二重引用符で囲んで使用する場合の標準の操作手順です。sedコマンドライン全体を表示するのではなくsed、OPが行ったように正規表現のコマンド文字列のみを表示するため、これらを回答に使用しませんでした。OPのようにファイルに入れれば、引用符は必要ありません。
ラーカー、

ええ、十分に公平です(多分それは言及されるかもしれませんが)。その例が役立ちます。私は時々たくさんのバックスラッシュを入れなければならないことを発見しています...そしてそれは本当に混乱します。例-e "s / '/ \\\\\\\&/ g"しかし、テキストは間違っていると思いますが、「Whichは\をfooに置き換えます」-「Whichは/をfooに置き換える」である必要がありますか?
Max Waterman

@ MaxWaterman \ vs /でそれをキャッチしてくれてありがとう。修正しました。sedシェルスクリプトにコマンドがある場合は、バックスラッシュを追加する必要がある場合があります(各バックスラッシュを再度バックスラッシュする必要があります)。
ラーカー、

105

sコマンドは、区切り文字として任意の文字を使用することができます。sが使用された後に来る文字は何でも。私はを使うように育てられました#。そのようです:

s#?page=one&#/page/one#g

5
OS XでsedされたBSDのmanページには、sコマンドについて次のように記載されています。パターンスペース内の正規表現の最初のインスタンスを置換文字列に置き換えます。REと置換を区切るために、スラッシュの代わりにバックスラッシュまたは改行以外の文字を使用できます。GNU sedのmanページに似たようなことが書かれているのは間違いないでしょう。
トムアンダーソン

現在受け入れられている回答は基本的にこれと同じで、1分前に投稿されました。
トムアンダーソン

61

sedについて非常に有用ですがあまり知られていない事実は、おなじみのs/foo/bar/コマンドがスラッシュだけでなく任意の句読点を使用できることです。一般的な代替手段はs@foo@bar@です。これから、問題を解決する方法が明らかになります。


スラッシュの代わりに使いたい場合の天才的なアドバイス。ありがとう!
mbb

9

特殊文字の前に\を追加します。

s/\?page=one&/page\/one\//g


4
私は何かを逃したかもしれませんが、これを試してみましたが、うまくいかないようです。試してみるのは当たり前のことのように思われましたが、私が正しく、実際に機能しない場合、なぜ投稿するのでしょうか。
codenoob 2016年

4
@codenoob(およびここにアクセスする他のユーザー)-先頭の「s」が必要です。s/foo\/bar/foo_bar/動作しますが動作し/foo\/bar/foo_bar/ません。
MynockSpit

5

私が開発しているシステムでは、sedに置き換えられる文字列は、変数に格納され、sedに渡されるユーザーからの入力テキストです。

この投稿で前述したように、sedコマンドブロック内の文字列にsedで使用される実際の区切り文字が含まれている場合、sedは構文エラーで終了します。次の例を検討してください。

これは機能します:

$ VALUE=12345
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345

これは壊れます:

$ VALUE=12345/6
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
sed: -e expression #1, char 21: unknown option to `s'

デフォルトの区切り文字を置き換えることは、sedが区切り文字として使用する特定の文字(たとえば「/」)をユーザーが入力するのを制限したくなかったので、私の場合は堅牢なソリューションではありません。

ただし、入力文字列内の区切り文字の出現をエスケープすると、問題が解決します。sedで解析する前に、入力文字列の区切り文字を体系的にエスケープする以下の解決策を検討してください。このようなエスケープは、sed自体を使用した置換として実装できます。この置換は、入力文字列に区切り文字が含まれている場合でも安全です。これは、入力文字列がsedコマンドブロックの一部ではないためです。

$ VALUE=$(echo ${VALUE} | sed -e "s#/#\\\/#g")
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345/6

これをさまざまなスクリプトで使用される関数に変換しました。

escapeForwardSlashes() {

     # Validate parameters
     if [ -z "$1" ]
     then
             echo -e "Error - no parameter specified!"
             return 1
     fi

     # Perform replacement
     echo ${1} | sed -e "s#/#\\\/#g"
     return 0
}

1
離れて私のためにあなたの答えからのテイクでは、あなたがDEF_VALUEを置き換えるために使用している値は、その中にスラッシュがある場合、その後、あなたは例えば仕事にsedのための3つのバックスラッシュでエスケープしなければならないということだったVALUE="01\\\/01\\\/2018"
alexkb

3

この行は3つの例で機能します。

sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' a.txt
  • 私は-rいくつかのエスケープを保存するために使用しました。
  • この行は、1、2、3の場合に一般的でなければなりません。サブを3回する必要はありません

あなたの例(a.txt)でテストしてください:

kent$  echo "?page=one&
?page=two&
?page=three&"|sed -r 's#\?(page)=([^&]*)&#/\1/\2#g'
/page/one
/page/two
/page/three


1

匿名からの素晴らしい回答。\ HTML文字列の引用符をエスケープしようとしたときの問題を解決しました。

したがって、sedを使用して(サーバー上の)HTMLテンプレートを返す場合は、単一の代わりに二重のバックスラッシュを使用します。

var htmlTemplate = "<div style=\\"color:green;\\"></div>";

1

sedあるS tream itor、その中にあなたが使用することができます|送信する(パイプ)を標準ストリームを通じて(STDINとSTDOUT、具体的に)sed、それUnixの哲学の伝統で便利なツール作り、その場でプログラム的にそれらを改変すること。ただし、-i下記のパラメータを使用して、ファイルを直接編集することもできます。
以下を検討してください

sed -i -e 's/few/asd/g' hello.txt

s/見つかった式を次のように置換するために使用されます:fewasd

少数、勇敢な。


asd、勇敢な。

/g「グローバル」の略で、行全体でこれを行うことを意味します。あなたが去る場合/g(としs/few/asd/、そこにいつもどんな3つのスラッシュがないように必要)とfew、最初の同じ行に2回表示fewに変更されましたasd

少数の男性、少数の女性、勇敢な。


asd男性、少数の女性、勇敢な。

これは、行頭の特殊文字を変更する場合など、状況によっては便利です(たとえば、一部の人々が電子メールスレッドの前の資料を引用するために使用する大なり記号を水平タブで置き換え、引用符で囲まれた代数の不等式を行の後半に残します)手付かず)、しかしあなたがそれを指定するあなたの例では どこでも few発生するようには、置換する必要があることを確認してください/g

次の2つのオプション(フラグ)が1つに結合されます-ie

-iオプションは、編集に使用されている私のファイルにn個の場所hello.txt

-eオプションはeを示しますこのような場合には、実行するためのXPRESSION /コマンドをs/

注:-i -e検索/置換にはを使用することが重要です。その場合-ie、「e」の文字が追加されたすべてのファイルのバックアップを作成します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.