echo -n 'I hate cats' > cats.txt
sed -i '' 's/hate/love/' cats.txt
これにより、ファイル内の単語が正しく変更されますが、ファイルの末尾に改行も追加されます。なんで?これは OSX でのみ発生し、Ubuntu などでは発生しません。どうすれば停止できますか?
echo -n 'I hate cats' > cats.txt
このコマンドは、'cats.txt' の内容に一重引用符で囲まれた 11 文字を入力します。この段階でcats.txtのサイズを確認すると、11バイトになっているはずです。
sed -i '' 's/hate/love/' cats.txt
このコマンドは、cats.txt ファイルを 1行ずつ読み取り、各行の最初の 'hate' が 'love' に置き換えられたファイルに置き換えます (そのようなインスタンスが存在する場合)。重要な部分は、線とは何かを理解することです。sed のマニュアルページから:
Normally, sed cyclically copies a line of input, not including its
terminating newline character, into a pattern space, (unless there is
something left after a ``D'' function), applies all of the commands
with addresses that select that pattern space, copies the pattern
space to the standard output, appending a newline, and deletes the
pattern space.
部分に注意してくださいappending a newline
。システムでは、終了改行がないにもかかわらず、sed はまだファイルを 1 行であると解釈しています。したがって、出力は 11 文字と改行が追加されたものになります。他のプラットフォームでは、これは必ずしも当てはまりません。sed は、実際には行ではないため、ファイルの最後の行を完全にスキップする (事実上削除する) 場合があります。しかし、あなたの場合、sedは基本的にファイルを修正しています(ファイルに行が含まれていないため、sedへの入力が壊れています)。
詳細については、こちらを参照してください:なぜテキスト ファイルは改行で終わる必要があるのですか?
問題に対する別のアプローチについては、この質問を参照してください: SED は最後に新しい行を追加します
改行を追加しないソリューションが必要な場合は、gsed
( brew install gnu-sed
)を使用できます
GNU sed は Mac OS では改行を追加しないことに注意してください。
これは私にとってはうまくいきました。中間ファイルを使用する必要はありませんでした。
OUTPUT=$( echo 'I hate cats' | sed 's/hate/love/' )
echo -n "$OUTPUT"
あなたができるもう一つのことはこれです:
echo -n 'I hate cats' > cats.txt
SAFE=$(cat cats.txt; echo x)
SAFE=$(printf "$SAFE" | sed -e 's/hate/love/')
SAFE=${SAFE%x}
そうすれば、cats.txt が改行で終わる場合、それは保持されます。そうでない場合は、追加されません。