編集したコンテンツを手動で新しいファイルにストリーミングし、新しいファイルの名前を元のファイル名に変更せずに、単一のsedコマンドでファイルを編集できるかどうかを確認しようとしています。私はその-i
オプションを試しましたが、私のSolarisシステムはそれ-i
が違法なオプションだと言っていました。別の方法はありますか?
編集したコンテンツを手動で新しいファイルにストリーミングし、新しいファイルの名前を元のファイル名に変更せずに、単一のsedコマンドでファイルを編集できるかどうかを確認しようとしています。私はその-i
オプションを試しましたが、私のSolarisシステムはそれ-i
が違法なオプションだと言っていました。別の方法はありますか?
回答:
この-i
オプションは、編集されたコンテンツを新しいファイルにストリーミングし、それを裏で名前を変更します。
例:
sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename
そして
sed -i '' 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename
上のMacOSの。
sed -i "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>
sed
適切な場所でファイルを編集する機能がないシステムでは、以下を使用する方がより良い解決策になると思いますperl
。
perl -pi -e 's/foo/bar/g' file.txt
これは一時ファイルを作成しますが、空の適切なサフィックス/拡張子が指定されているため、元のファイルを置き換えます。
sudo
。私の考えでは、最新のGNUまたはBSDをインストールせずに一時ファイルを手動で作成して名前を変更しないようにする方法についての質問ですsed
。Perlを使用するだけです。
sed 's/foo/bar/g' file.txt > file.tmp && mv file.tmp file.txt
。インプレース編集が一時ファイルを使用して名前を変更するからといって、オプションが使用できない場合に手動で名前を変更する必要があるという意味ではありません。彼/彼女が望むことを行うことができる他のツールが世の中にあり、Perlは明白な選択です。これは元の質問に対する答えではないのですか?
sed
。質問は実際には非常に良いものでしたが、manページを読むことができないか、SOで実際に質問を読むことに煩わされない人々によって、その価値は減少しています。
OS Xでは、このコマンドを実行すると、「無効なコマンドコード」などの奇妙なエラーやその他の奇妙なエラーが発生する場合があります。この問題を解決するには、
sed -i '' -e "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>
これは、OSXバージョンのsed
では-i
オプションがextension
引数を期待するため、コマンドは実際にはextension
引数として解析され、ファイルパスはコマンドコードとして解釈されます。ソース:https : //stackoverflow.com/a/19457213
brew install gnu-sed
とともにはPATH
あなたがのsedのGNUバージョンを使用できるようになります。言及していただきありがとうございます。明確な頭のスクラッチャー。
以下は私のMacで正常に動作します
sed -i.bak 's/foo/bar/g' sample
サンプルファイルでは、fooをbarに置き換えています。元のファイルのバックアップは、sample.bakに保存されます
バックアップなしでインライン編集するには、次のコマンドを使用します
sed -i'' 's/foo/bar/g' sample
もう一つ注意すべき、sed
sedを唯一の目的として、独自に書き込み、ファイルできない「ストリーム」(つまり標準入力、標準出力、標準エラー出力、および他のパイプラインの編集者として働くことで>&n
、バッファ、ソケットなど)。これを念頭に置いて、別のコマンドtee
を使用して出力をファイルに書き戻すことができます。別のオプションは、コンテンツをにパイプしてパッチを作成することdiff
です。
ティー方式
sed '/regex/' <file> | tee <file>
パッチ方式
sed '/regex/' <file> | diff -p <file> /dev/stdin | patch
更新:
また、patchはファイルをdiff出力の1行目から変更することに注意してください。
これはdiffからの出力の最初の行にあるため、パッチはどのファイルにアクセスするかを知る必要はありません。
$ echo foobar | tee fubar
$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin
*** fubar 2014-03-15 18:06:09.000000000 -0500
--- /dev/stdin 2014-03-15 18:06:41.000000000 -0500
***************
*** 1 ****
! foobar
--- 1 ----
! fubar
$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin | patch
patching file fubar
/dev/stdin 2014-03-15
、1月7日の回答 -あなたはタイムトラベラーですか?
/dev/stdin
あなたは交換する必要がありますので、存在しません/dev/stdin
:「 - 」で以下のコマンドが動作するはずですので、引用符、ハイフンを$ sed 's/oo/u/' fubar | diff -p fubar -
して$ sed 's/oo/u/' fubar | diff -p fubar - | patch
patch
切り捨てられないかどうかはわかりません。出力を別のファイルに保存してから、cat
元のファイルに保存する方が安全だと思います。
あなたが望むことをすることは不可能ですsed
。sed
その-i
場でファイルを編集するオプションをサポートするバージョンでも、明示的に望まないことを実行します。一時ファイルに書き込み、ファイルの名前を変更します。しかし、おそらくあなたは単に使用することができますed
。たとえば、ファイル内のすべての出現をに変更foo
するbar
にはfile.txt
、次のようにします。
echo ',s/foo/bar/g; w' | tr \; '\012' | ed -s file.txt
構文はに似ています sed
いますが、完全に同じではありません。
ただし、名前を変更した一時ファイルを使用しない理由を検討する必要があるかもしれません。-i
サポートがない場合でも、sed
簡単にスクリプトを作成して作業を行うことができます。代わりにsed -i 's/foo/bar/g' file
、あなたがすることができますinline file sed 's/foo/bar/g'
。このようなスクリプトを書くのは簡単です。例えば:
#!/bin/sh -e
IN=$1
shift
trap 'rm -f $tmp' 0
tmp=$( mktemp )
<$IN "$@" >$tmp && cat $tmp > $IN # preserve hard links
ほとんどの用途に適しています。
inline
し、それを呼び出すように、上記説明:inline inputfile sed 's/foo/bar/g'
ed
本当にその場で行う答えのみ。初めて必要ed
です。ありがとうございました。少しの最適化は、使用するecho -e ",s/foo/bar/g\012 w"
かecho $',s/foo/bar/g\012 w'
、シェルが余分なtr
呼び出しを回避できるようにする場所です。
ed
変更は実際には行われません。strace
出力から、GNU ed
は一時ファイルを作成し、変更を一時ファイルに書き込んでから、ハードリンクを保持しながら元のファイル全体を書き換えます。truss
出力から、Solaris 11 ed
は一時ファイルも使用しますが、w
コマンドを使用して保存すると、一時ファイルの名前を元のファイル名に変更し、ハードリンクを破棄します。
ed
現在のMacOS(モハーベ、何でもそのマーケティングの専門用語の意味)と船がまだハードリンクを保持していること。YMMV
sedはインプレース編集をサポートしています。からman sed
:
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
例:
次hello.txt
のテキストを含むファイルがあるとします。
hello world!
古いファイルのバックアップを保持したい場合は、以下を使用します。
sed -i.bak 's/hello/bonjour' hello.txt
最終的に2つのファイルが作成されます。hello.txt
内容は次のとおりです。
bonjour world!
そしてhello.txt.bak
古い内容で。
コピーを保持したくない場合は、extensionパラメータを渡さないでください。
リダイレクト演算子<>
を使用して、ファイルを開いて読み書きすることもできます。
sed 's/foo/bar/g' file 1<> file
ライブで見る:
$ cat file
hello
i am here # see "here"
$ sed 's/here/away/' file 1<> file # Run the `sed` command
$ cat file
hello
i am away # this line is changed now
Bashリファレンスマニュアルから→3.6.10読み取りおよび書き込み用にファイル記述子を開く:
リダイレクト演算子
[n]<>word
ワードの拡張である名前のファイルが、ファイル記述子nで、またはnが指定されていない場合はファイル記述子0で、読み取りと書き込みの両方のために開かれます。ファイルが存在しない場合は作成されます。
MoneypennyがSkyfallで言ったように:「時々古い方法が最善です。」キンケードは後で同様のことを言った。
$ printf ',s/false/true/g\nw\n' | ed {YourFileHere}
適切な編集を行います。ファイルを書き込むために「\ nw \ n」を追加しました。リクエストへの回答の遅延についてお詫びします。
|
ます。@MattMontag
\n
。[範囲] s / <old> / <new> / <flag>は代替コマンドの形式です-他の多くのテキストエディタでまだ見られるパラダイム(そう、vim、edの直接の子孫)とにかく、g
フラグは「グローバル」、および「あなたが見る各行のすべてのインスタンス」を意味します。範囲3,5
は3〜5行目です。,5
StartOfFile-5、3 3,
行目からEndOfFile、,
StartOfFile-EndOfFileを確認します。「false」を「true」に置き換える、すべての行のグローバル置換コマンド。次に、書き込みコマンドw
が入力されます。
-i
gnu sedのオプションですが、標準sedにはありません。ただし、コンテンツを新しいファイルにストリーミングしてから、ファイルの名前を変更するため、希望どおりにはなりません。