Linuxでテキストを検索/置換するために、次のsed
コマンドを使用しました。
sed -i 's/old_link/new_link/g' *
しかし、私は私のMac OS X上でそれを試してみると、私は得る:
"コマンドcは\の後にテキストが続くことを想定しています"
私のMacは普通のBASHシェルを実行していると思いました。どうしたの?
編集:
@ High Performanceによると、これはMacのsed
が異なる(BSD)フレーバーであるためです。したがって、私の質問はBSD sed
でこのコマンドをどのように複製するのかということです。
編集:
これを引き起こす実際の例はここにあります:
sed -i 's/hello/gbye/g' *
-i
オプションを使用する場合は、バックアップの拡張子を指定する必要があります。
あなたが持っている場合:
File1.txt
File2.cfg
コマンド(新しいバージョンのMacとGNUで動作するようにするには、-i
と''
および-e
の間にスペースがないことに注意してください)。
sed -i'.original' -e 's/old_link/new_link/g' *
次のように2つのバックアップファイルを作成します。
File1.txt.original
File2.cfg.original
すべての場合に有効なsedコマンドの組み合わせを見つけることは不可能であるため、バックアップファイルを作成することを避けるための移植性のある方法はありません。
sed -i -e ...
- -e
バックアップを作成するため、OS Xでは機能しませんsed -i'' -e ...
- OS X 10.6では動作しませんが10.9以降で動作しますsed -i '' -e ...
- GNUに取り組んでいない注すべてのプラットフォームで機能するsedコマンドがあるわけではないので、別のコマンドを使用して同じ結果を得ることができます。
例:Perl -i -pe's/old_link/new_link/g' *
私はあなたがバックアップファイルのための拡張子-iを使うとき、私はOS Xを信じています必須。試してください:
sed -i .bak 's/hello/gbye/g' *
GNU sed
を使用すると、拡張子はオプションになります。
これはGNUとBSDの両方のsedで動作します。
sed -i'' -e 's/old_link/new_link/g' *
またはバックアップ付き:
sed -i'.bak' -e 's/old_link/new_link/g' *
-i
オプションの後にスペースがないことに注意してください。 (GNU sedに必要)
Macでも同じ問題があり、brew
で解決しました。
brew install gnu-sed
そしてとして使用
gsed SED_COMMAND
sed
をgsed
のエイリアスとして設定することもできます(必要な場合)。
alias sed=gsed
または、gsedというGNUバージョンのsedをMacにインストールして、標準のLinux構文を使用して使用することもできます。
そのためには、gsed
をportsを使ってインストールします(持っていないのなら、Sudo port install gsed
を実行して http://www.macports.org/ で入手してください)。その後、sed -i 's/old_link/new_link/g' *
を実行できます。
あなたのMacは確かにBASHシェルを走らせています、しかしこれはあなたが扱っているsedのどの実装のもっと問題です。 Macでは、sedはBSDから来ており、典型的なLinuxマシンで見られるsedとは微妙に異なります。私はあなたにman sed
を勧めます。
Sinetrisの答えは正しいですが、私はこれをfind
コマンドと共に使用して、変更したいファイルについてより具体的にします。一般にこれはうまくいくはずです(osx /bin/bash
でテスト済み):
find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;
一般に、複雑なプロジェクトでsed
を指定せずにfind
を使用すると、効率が悪くなります。
環境変数をテンプレートファイルに適用する方法は次のとおりです(バックアップは不要)。
echo "Hello {{FOO}}" > foo.conf.tmpl
FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf
macOS 10.12.4とbuntu 14.04.5の両方を動作させる
sed -ie 's/old_link/new_link/g' *
BSDとLinuxの両方で動作します
他の答えが示すように、バックアップファイルを作成せずにOS XとLinuxの間でsedを使い分ける方法はありません。そのため、私は代わりにこのRubyのワンライナーを使用しました。
Ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml
私の場合は、rake
タスクから(つまり、Rubyスクリプト内で)それを呼び出す必要があったので、この追加レベルの引用を使用しました。
sh %q{Ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}
私は、MacOS(MacOS 10.12でテスト済み)と他のOSとの間のsed
の違いを処理するための関数を作成しました。
OS=`uname`
# $(replace_in_file pattern file)
function replace_in_file() {
if [ "$OS" = 'Darwin' ]; then
# for MacOS
sed -i '' -e "$1" "$2"
else
# for Linux and Windows
sed -i'' -e "$1" "$2"
fi
}
使用法:
$(replace_in_file 's,MASTER_Host.*,MASTER_Host='"$MASTER_IP"',' "./mysql/.env")
どこで:
,
は区切り文字です
's,MASTER_Host.*,MASTER_Host='"$MASTER_IP"','
はパターンです
"./mysql/.env"
はファイルへのパスです