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のバージョン間の別の違いを理解していませんか?
厳密に言えば、 POSIX仕様のsed
の場合、a\
の後に改行が必要です。
[1addr]a\ text
前述のように、テキストを標準出力に書き込みます。
これにより、ワンライナーを書くのが少し面倒になります。これがおそらく、次の理由です GNU拡張a
、i
、および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)
この回答 で説明されているように、i
やa
などの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
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に負っているので、単純な置換などの構文はそれほど急な学習曲線ではないことを急いで付け加えます。
GNU sedは、私がとにかく使用した例/チュートリアルに基づいて、POSIX sedよりもはるかに一般的に使用されているようです。
私が使用しているOSXマシンにGNU sedをインストールする方がはるかに簡単であることがわかりました。もし興味があれば、これを行う最良の方法は Homebrew からインストールすることです。
$ brew install gnu-sed
を使用するか、$ brew install coreutils
を使用してすべての一般的なGNUユーティリティを取得できます。
次に、date
またはその他のプログラムで構文の問題が発生した場合は、GNUバージョンを使用できます。結局、私は常にGNUバージョンを使用し、PATH
にシステムバージョンより前に置く方が簡単だと判断しました。