web-dev-qa-db-ja.com

OSX挿入の特定の行でsed

Linuxでしばらく「sed」を使用してきましたが、「POSIX sed」と「GNU sed」には多くの小さな違いがあるため、OSXで使用するのに少し苦労しました。現在、特定の行番号の後にテキスト行を挿入する方法に苦労しています。 (この場合、4行目)

Linuxでは次のようにします。

sed --in-place "4 a\  mode '0755'" file.txt

だからOSXで私はこれを試しました:

sed -i "" "4 a\ mode '0755'" file.txt

ただし、これにより、「コマンドの最後にある\の後の余分な文字」エラーが引き続き表示されます。ここで何が問題になっていますか?タイプミスはありますか?または、sedのバージョン間の別の違いを理解していませんか?

24
CRThaze

厳密に言えば、 POSIX仕様のsed の場合、a\の後に改行が必要です。

[1addr]a\
text

前述のように、テキストを標準出力に書き込みます。

これにより、ワンライナーを書くのが少し面倒になります。これがおそらく、次の理由です GNU拡張ai、およびcコマンド:

GNU拡張子として、aと改行の間に空白-\シーケンス以外がある場合、この行のテキストは、 aの後の最初の空白以外の文字は、textブロックの最初の行と見なされます(これにより、1行の追加のスクリプトを簡略化できます。 )この拡張機能は、iおよびcコマンドでも機能します。

したがって、sed構文で移植可能にするには、a\の後に改行を含める必要があります。最も簡単な方法は、引用符で囲まれた改行を挿入することです。

$ sed -e 'a\
> text'

$>はシェルプロンプトです)。苦痛を感じる場合は、bash [1]にCスタイルのエスケープを挿入するための $' ' 引用構文があるので、

sed -e 'a\'$'\n''text'

[1]とmksh(r39b +)およびいくつかの非bashボーンシェル(たとえば、FreeBSD 9+の/ bin/sh)

25
jw013

この回答 で説明されているように、iaなどのsedコマンドを使用して複数の-e "..."句を使用すると便利です。これらの各句は改行で区切られていると理解されます。 iコマンドとaコマンドは、インラインsedスクリプトで使用するのが難しいです(sed -f file ...を使用して呼び出される複数行sedスクリプトファイルで使用するように設計されています)。 -e句の最後に導入された暗黙の改行を使用して、a\と追加するテキストの行を区切ることはできないようです。ただし、追加するテキストの行を終了するために使用できます。

この特定のケースでは、あなたがやろうとしていることは、実際には単一の-e ...句で達成されるかもしれません。 aコマンドを正しく使用するだけです。 POSIX標準では、aの後に\が続き、その後に改行が必要です。その後、次の行の残りの部分が挿入されます(改行または末尾まで) -e句が見つかりました)。だからあなたはできる:

sed -i "" -e $'4 a\\\n'"mode '0755'" file.txt
14
dubiousjim

Perlは、このようなプラットフォームに依存するGNU対非GNU対「独自の」特異性に悩まされることはありません。

Perl -ni.old -e 'print;if ($.==4) {print "mode 0755\n"}' file

-n' option creates a loop that reads every line of the input file. Unlike its cousin- p(not used here) it doesn't automatically print every line read. The-私invokes in-place replacement. The argument to-私(viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -eはスクリプトの開始を示します。

$.は、line-1から始まる行番号を示します。したがって、コマンドラインは 'file'を読み取り、line-numberが4に等しい場合、その行の後に挿入したいものを続けて出力します。

Perlはそのルーツをsed、AWK、Cに負っているので、単純な置換などの構文はそれほど急な学習曲線ではないことを急いで付け加えます。

5
JRFerguson

GNU sedは、私がとにかく使用した例/チュートリアルに基づいて、POSIX sedよりもはるかに一般的に使用されているようです。

私が使用しているOSXマシンにGNU sedをインストールする方がはるかに簡単であることがわかりました。もし興味があれば、これを行う最良の方法は Homebrew からインストールすることです。

$ brew install gnu-sedを使用するか、$ brew install coreutilsを使用してすべての一般的なGNUユーティリティを取得できます。

次に、dateまたはその他のプログラムで構文の問題が発生した場合は、GNUバージョンを使用できます。結局、私は常にGNUバージョンを使用し、PATHにシステムバージョンより前に置く方が簡単だと判断しました。

5
Dean