\ nや\ tなどのエスケープシーケンスを解釈するようにBSD sedに指示するにはどうすればよいですか?


14

sedGNUと同様にBSDと互換性を持ちたいsedの代替コマンドがありますsed。この場合、拡張正規表現は必要ないため、拡張正規表現は問題になりません。私の主な問題は、2つsedのsが置換文字列の文字エスケープシーケンスを解釈する方法の違いです。私の置換文字列にはタブと改行が含まれており、メンテナンスを容易にするためにコマンド文字列に表示したいのですが、BSD sedはエスケープシーケンスを解釈せず、GNU sed はそうします。sedBSDでこれらのエスケープシーケンスを解釈するように指示する適切な方法は何ですか?次の2つのスニペットは、私の問題を要約しています。

GNU sed

echo ABC | sed 's/B/\n\tB\n'

eil

A
    B
C

BSD sed

echo ABC | sed 's/B\n\tB\n'

利回り

AntBnC

明らかに、\nそして\tBSDによってエスケープシーケンスとして解釈されていませんsed

さて、私の質問に。BSD sedマンページによると:

置換文字列に改行文字を指定するには、その前にバックスラッシュを付けます。

これは、リテラルの改行の前にバックスラッシュを付ける必要があることを意味していますか?置換テキストのsedよう\nにエスケープシーケンスを解釈するよう指示する適切な方法は何ですか?


2
BSD sedはGNU sedではなく、出力でこのようなエスケープをサポートしているとは思わない。リテラル文字を挿入するか、GNU sedをインストールするか、awkのようなエスケープをサポートするものに切り替える必要があります。
jw013

@ jw013、私は2つの違いを明確にしています。GNU sedのインストールはオプションではありません。私が望んでいることを達成するために2つの間に十分な共通点を見つけたいと思っていましたsed。最終的には、awkを使用するのが理にかなっているでしょう。それで、私が引用したBSD sedマンページの解釈についてどう思いますか?
ephsmith

2
はい、リテラルのタブと改行を使用する必要があります。改行を使用する場合は、バックスラッシュを前に付ける必要がありますが、これは基本的に単なる行継続メカニズムです。
jw013

@ jw013、素晴らしい返信をありがとう。この時点で、メンテナンスのために、あなたのアドバイスを受け取り、私のソリューションをawkで作り直します。
ephsmith

良い選択
-awk

回答:


6

ポータブルスクリプトを記述する必要がある場合は、POSIX標準(別名シングルUnix別名オープングループベース仕様)の機能に固執する必要があります。Issue 7別名POSIX-1.2008は最新ですが、多くのシステムはまだそれを採用し終えていません。POSIX-1.2001としても知られる第6号は、すべての近代的な大学によって広く提供されています。

sedの、のようなエスケープシーケンスの意味を\t\nであることを除いて、移植性がありません正規表現\n改行を表します。sコマンドの置換テキストで\nは、移植性はありませんが、改行を表すシーケンスbackslash-newlineを使用できます。

タブ文字(または8進数で表現された他の文字)を生成する移植可能な方法は、trです。文字をシェル変数に保存し、sedスニペットでこの変数を置き換えます。

tab=$(echo | tr '\n' '\t')
escape=$(echo | tr '\n' '\033')
embolden () {
  sed -e 's/^/'"$escape"'[1m/' -e 's/$/'"$escape"'[0m/'
}

改行は、正規表現とs置換テキストで別々に表現する必要があることに再度注意してください。

代わりにawkを使用することもできます。\oooすべての文字列リテラルで、8進エスケープを含むバックスラッシュエスケープを許可します。


7

$'...'文字列をに渡す前に、bashクォートを使用してエスケープを解釈できますsed

bashのmanページから:

   Words  of  the  form  $'string'  are  treated specially.  The word
   expands to string, with backslash-escaped characters  replaced  as
   specified  by the ANSI C standard.  Backslash escape sequences, if
   present, are decoded as follows:
          \a     alert (bell)
          \b     backspace
          \e     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \nnn   the eight-bit character whose  value  is  the  octal
                 value nnn (one to three digits)
          \xHH   the eight-bit character whose value is the hexadeci-
                 mal value HH (one or two hex digits)
          \cx    a control-x character

   The expanded result is single-quoted, as if the  dollar  sign  had
   not been present.

   A  double-quoted  string  preceded by a dollar sign ($) will cause
   the string to be translated according to the current  locale.   If
   the  current locale is C or POSIX, the dollar sign is ignored.  If
   the string is translated and replaced, the replacement is  double-
   quoted.

3

これは、スタックオーバーフローで解決されています。

/programming/1421478/how-do-i-use-a-new-line-replacement-in-a-bsd-sed

それはほとんどjw013が言ったこととまったく同じです。

リテラルタブタイプctrl+ を挿入するためVTab


参考に感謝します。私のグーグル検索がそのリンクを返さなかったことを嫌い:D
ephsmith

1
ctrl-Vタブの提案は、シェルに依存しています。たとえば、魚では機能しません。
anddam

魚を一度も使ったことがないので気づきませんでしたが、知っていてよかったです。
バハマ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.