ディレクトリ内のすべての*.phpファイルを列挙し、iconv
を適用するbashスクリプトがあります。 それに。これはSTDOUTに出力されます。
-o
を追加してから パラメータ(私の経験では)は、おそらく変換が行われる前に実際に空白のファイルを書き込みますが、変換を実行してから入力ファイルを上書きするようにスクリプトを調整するにはどうすればよいですか?
for file in *.php
do
iconv -f cp1251 -t utf8 "$file"
done
承認された回答:
iconv
が原因で、これは機能しません 最初に出力ファイルを作成し(ファイルはすでに存在するため、切り捨てます)、次に入力ファイル(現在は空です)の読み取りを開始します。ほとんどのプログラムはこのように動作します。
出力用の新しい一時ファイルを作成してから、所定の位置に移動します。
for file in *.php
do
iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
mv -f "$file.new" "$file"
done
プラットフォームのiconv
の場合 -o
がありません 、シェルリダイレクトを使用して同じ効果を得ることができます。
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
mv -f "$file.new" "$file"
done
コリンワトソンのsponge
ユーティリティ(Joey Hessのmoreutilsに含まれています)はこれを自動化します:
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done
この回答は、iconv
だけに当てはまるわけではありません。 しかし、どんなフィルタープログラムにも。言及する価値のあるいくつかの特別なケース:
- GNUsedおよびPerl
-p
-i
があります 所定の場所でファイルを置き換えるオプション。 - ファイルが非常に大きい場合、フィルターは一部の部分を変更または削除するだけで、追加することはありません(例:
grep
、tr
、sed 's/long input text/shorter text/'
)、危険な生活が好きな場合は、ファイルをそのまま変更することをお勧めします(ここで説明する他のソリューションでは、新しい出力ファイルを作成し、最後に移動します。そのため、コマンドが中断されても元のデータは変更されません。何らかの理由で)。