sed
LinuxとMacの両方で機能するバックアップなしのtodoインプレース編集の呼び出しはありますか?sed
OS Xに同梱されているBSD はを必要sed -i '' …
としているようですが、GNU sed
Linuxディストリビューションは通常、引用符を(バックアップ拡張子ではsed -i …
なく)空の入力ファイル名として解釈し、代わりに必要です。
両方のフレーバーで機能するコマンドライン構文はありますか?したがって、両方のシステムで同じスクリプトを使用できますか?
sed
LinuxとMacの両方で機能するバックアップなしのtodoインプレース編集の呼び出しはありますか?sed
OS Xに同梱されているBSD はを必要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
ファイルを削除することもできます。
sed
sed
いません)では、位置を受け入れませんcommand
呼び出されたときに引数を-i
— 別のフラグで指定する必要があります-e
。このように、コマンドは次のようになりますsed -i.bak -e 's/foo/bar/' filename
sed -i.bak 's/foo/bar/' file && rm file.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
''
。とのです。-i
と-i''
シェルの解析時は同じであることに注意してください。最初の2つの呼び出しでは、まったく同じ引数を取得するため、異なる動作をするsed
ことはできません。
ほとんどのスクリプトはGNU sedバージョン用に記述されているため、OSXの場合、スクリプトでの問題を回避するために、Homebrewを介して常にGNU sedバージョンをインストールします。
brew install gnu-sed --with-default-names
その後、BSD sedはGNU sedに置き換えられます。
または、デフォルト名なしでインストールできますが、その後:
PATH
インストール後に指示どおりにgnu-sed
gsed
またはsed
システムに応じて選択してください--with-default-names
は自作コアから削除されましたました、この回答の詳細情報。インストール時にgnu-sed
、今、インストール手順は、追加する必要があることを指定しgnubin
、あなたにPATH
:PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"
以下のようNoufalイブラヒムは尋ねる、なぜあなたは、Perlを使用することはできませんか?どのMacにもPerlがあり、ベースシステムに一部のバージョンのPerlを含まないLinuxまたはBSDディストリビューションはほとんどありません。実際にPerlが不足している可能性がある唯一の環境の1つは、BusyBox(GNU / Linuxのように機能する)です。-i
バックアップ拡張を指定できないことを除いて、機能します)。
イスマイルは、推奨しています
perlはどこでも利用できるので、
perl -pi -e s,foo,bar,g target.file
そして、これはほとんどの場合、sed -i
GNU / LinuxとBSD / Macの間の基本的な非互換性に対処するためのスクリプト、エイリアス、またはその他の回避策よりも優れたソリューションのようです。
perl
2009年5月1日以降、Linux Standard Base仕様の一部です。refspecs.linuxfoundation.org
それを機能させる方法はありません。
1つの方法は、次のような一時ファイルを使用することです。
TMP_FILE=`mktemp /tmp/config.XXXXXXXXXX`
sed -e "s/abc/def/" some/file > $TMP_FILE
mv $TMP_FILE some/file
これは両方で機能します
回答:いいえ。
最初に受け入れられた回答は、実際には要求されたものを実行しません(コメントに記載されています)。(a file-e
がディレクトリに「ランダムに」表示された理由を探しているときに、この答えが見つかりました。)
sed -i
MacOSとLinucesの両方で一貫して作業する方法がないようです。
私が推奨するのは、その価値のあるものとして、sed
(複雑な障害モードがある)を使ってその場で更新するのではなく、新しいファイルを生成して、後で名前を変更することです。つまり、を避け-i
ます。
この-i
オプションはPOSIX Sedの一部ではありません。より移植性の高い方法は、ExモードでVimを使用することです。
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
これはバックアップファイルを作成せず、引用符が付加されたファイルも作成しません。
sedi=(-i) && [ "$(uname)" == "Darwin" ] && sedi=(-i '')
sed "${sedi[@]}" -e 's/foo/bar/' target.file
スティーブパウエルの答えはです。OSXとLinux(Ubuntu 12.04)のsedのMANページを参照すると、2つのオペレーティングシステム間での「インプレース」のsedの使用における非互換性が明らかになっています。
JFYI、-iとLinuxバージョンのsedを使用する引用符(空のファイル拡張子を示す)の間にはスペースを入れないでください。
#Linux
sed -i""
そして
#OSX (notice the space after the '-i' argument)
sed -i ""
エイリアスのコマンドとbash 'if'内の ' uname 'のOS名出力を使用して、スクリプトでこれを回避しました。OSに依存するコマンド文字列を変数に格納しようとすると、引用符を解釈するときに失敗しました。スクリプト内で定義されたエイリアスを展開/使用するには、「shopt -s expand_aliases」を使用する必要があります。shoptの使用法はここで処理されます。
スクリプトsed
内でインプレースを実行する必要があり、インプレースでbash
.bkpファイルが生成されないようにし、OSを検出する方法がある場合(たとえば、ostype.shを使用)、-次のbash
組み込みシェルによるハックは機能する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の自作)にあります。
パイプからすべてのコンテンツをバッファリングし、パイプが閉じるまで待機し(おそらく入力ファイルがすでに閉じていることを意味します)、次に上書きします。
manページから:
あらすじ
sed '...'ファイル| grep '...' | スポンジファイル
LinuxとOS Xでは次のように動作します。
sed -i' ' <expr> <file>
たとえばをf
含むファイルaaabbaaba
sed -i' ' 's/b/c/g' f
aaaccaaca
LinuxとMacの両方で利回り。注引用符で囲まれた文字列があるスペースを含むと、スペースなしの間で-i
、文字列が。一重引用符または二重引用符はどちらも機能します。
Linuxではbash
、Ubuntu 14.04.4でバージョン4.3.11を、OS X 10.11.4 El Capitan(Darwin 15.4.0)でMacバージョン3.2.57を使用しています。