LinuxとMacの両方で機能する、バックアップなしのsed
todoインプレース編集の呼び出しはありますか? OS Xに同梱されているBSD sed
にはsed -i '' …
が必要と思われますが、GNU sed
Linuxディストリビューションには通常、引用符が空の入力ファイル名として解釈されますバックアップ拡張機能)、代わりにsed -i …
が必要です。
両方のフレーバーで機能するコマンドライン構文はありますか?両方のシステムで同じスクリプトを使用できますか?
本当にsed -i
を '簡単に'使用したいだけなら、次のことはGNUとBSD/Mac sed
の両方で機能します:
sed -i.bak 's/foo/bar/' filename
スペースとドットの不足に注意してください。
証明:
# GNU sed
% sed --version | head -1
GNU sed version 4.2.1
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
# BSD sed
% sed --version 2>&1 | head -1
sed: illegal option -- -
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
明らかに、.bak
ファイルを削除することができます。
これはGNU sedで機能しますが、OS Xでは機能しません。
sed -i -e 's/foo/bar/' target.file
sed -i'' -e 's/foo/bar/' target.file
これはOS Xで機能しますが、GNU sedでは機能しません。
sed -i '' -e 's/foo/bar/' target.file
OS Xでは
sed -i -e
に設定されるため、-e
を使用できませんsed -i'' -e
を使用することはできません。-i
と''
の間にスペースが必要です。OSXでは、ほとんどのスクリプトはGNU sedバージョン用に作成されているため、スクリプトの問題を回避するために、常にHomebrewを介してGNU sedバージョンをインストールします。
brew install gnu-sed --with-default-names
その後、BSD sedはGNU sedに置き換えられます。
または、デフォルト名なしでインストールできますが、次のようにします。
動作させる方法はありません。
1つの方法は、次のような一時ファイルを使用することです。
TMP_FILE=`mktemp /tmp/config.XXXXXXXXXX`
sed -e "s/abc/def/" some/file > $TMP_FILE
mv $TMP_FILE some/file
これは両方で動作します
Noufal Ibrahim が尋ねているように、なぜPerlを使用できないのですか?どのMacにもPerlが搭載されており、ベースシステムにPerlの一部のバージョンが含まれていないLinuxまたはBSDディストリビューションはほとんどありません。実際にPerlを欠くかもしれない唯一の環境の1つはBusyBoxです(-i
のGNU/Linuxのように動作しますが、バックアップ拡張機能を指定できないことを除きます)。
ismail が推奨するように、
Perlはどこでも利用できるので、ただ
Perl -pi -e s,foo,bar,g target.file
gNU/LinuxとBSD/Mac間のsed -i
の根本的な非互換性に対処するためのスクリプト、エイリアス、またはその他の回避策よりも、これはほとんどの場合、より優れたソリューションのようです。
回答:いいえ.
最初に受け入れられた答えは、実際には要求されたことを行いません(コメントに記載されています)。 (file-e
がディレクトリに「ランダムに」表示された理由を探しているときに、この答えを見つけました。)
MacOSとLinucesの両方でsed -i
を一貫して動作させる方法は明らかにありません。
価値があるものとして、私の推奨事項は、sed
(複雑な障害モードがあります)でその場で更新するのではなく、新しいファイルを生成して後で名前を変更することです。つまり、-i
を避けます。
-i
オプションは POSIX Sed の一部ではありません。より移植性の高い方法は、VimをExモードで使用することです。
ex -sc '%s/alfa/bravo/|x' file
%
すべての行を選択
s
置換
x
保存して閉じる
LinuxとmacOSでeval
を使用せずに、バックアップファイルを削除することなく機能する別のバージョンを次に示します。 sed
パラメーターを格納するためにBash配列を使用します。これは、eval
を使用するよりもクリーンです。
# Default case for Linux sed, just use "-i"
sedi=(-i)
case "$(uname)" in
# For macOS, use two parameters
Darwin*) sedi=(-i "")
esac
# Expand the parameters in the actual call to "sed"
sed "${sedi[@]}" -e 's/foo/bar/' target.file
これにより、バックアップファイルは作成されず、引用符が付加されたファイルも作成されません。
Steve Powellの答え は非常に正確です。OSXおよびLinux(Ubuntu 12.04)のsedのMANページを参照すると、2つの「インプレース」sed使用法の非互換性が強調されますオペレーティングシステム。
JFYI、Linuxバージョンのsedを使用する場合、-iと引用符(空のファイル拡張子を示す)の間にスペースがあってはなりません。したがって、
#Linux
sed -i""
そして
#OSX (notice the space after the '-i' argument)
sed -i ""
Alias'dコマンドとbash 'if'内の 'uname'のOS名出力を使用して、スクリプトでこれを回避しました。 OS依存のコマンド文字列を変数に保存しようとすると、引用符を解釈するときにヒットとミスが発生しました。スクリプト内で定義されたエイリアスを展開/使用するには、「shopt -s expand_aliases」を使用する必要があります。 shoptの使用法は here で処理されます。
私はこの問題に遭遇しました。唯一の簡単な解決策は、Macのsedをgnuバージョンに置き換えることでした。
brew install gnu-sed
sed
スクリプトでbash
インプレースを実行する必要があり、そのインプレースが.bkpファイルで生成されたくない場合、OSを検出する方法があります(たとえば、 ostype.sh )、-を使用すると、bash
Shellビルトインeval
を使用した次のハックが機能します。
OSTYPE="$(bash ostype.sh)"
cat > myfile.txt <<"EOF"
1111
2222
EOF
if [ "$OSTYPE" == "osx" ]; then
ISED='-i ""'
else # $OSTYPE == linux64
ISED='-i""'
fi
eval sed $ISED 's/2222/bbbb/g' myfile.txt
ls
# GNU and OSX: still only myfile.txt there
cat myfile.txt
# GNU and OSX: both print:
# 1111
# bbbb
# NOTE:
# if you just use `sed $ISED 's/2222/bbbb/g' myfile.txt` without `eval`,
# then you will get a backup file with quotations in the file name,
# - that is, `myfile.txt""`
スポンジを使用できます。スポンジは古いunixプログラムで、moreutilsパッケージ(ubuntuおよびおそらくdebianの両方、およびmacのhomebrew)に含まれています。
パイプのすべてのコンテンツをバッファリングし、パイプが閉じるまで待機し(おそらく入力ファイルが既に閉じていることを意味します)、次に上書きします。
manページ から:
あらすじ
sed '...'ファイル| grep '...' |スポンジファイル
LinuxおよびOS Xでは次のように機能します。
sed -i' ' <expr> <file>
例えばf
を含むファイルaaabbaaba
の場合
sed -i' ' 's/b/c/g' f
linuxとMacの両方でaaaccaaca
を生成します。引用符で囲まれた文字列スペースを含むがあり、-i
と文字列の間にスペースなしがあることに注意してください。一重引用符または二重引用符の両方が機能します。
Linuxでは、Ubuntu 14.04.4ではbash
バージョン4.3.11を使用し、OS X 10.11.4 El Capitan(Darwin 15.4.0)ではMacバージョン3.2.57を使用しています。