med*_*iev 79 shell io-redirection text-processing
我有一个 bash 脚本,它枚举目录中的每个 *.php 文件并应用于iconv它。这将在 STDOUT 中获得输出。
由于添加-o参数(根据我的经验)实际上可能在转换发生之前写入一个空白文件,我如何调整我的脚本以进行转换,然后覆盖输入文件?
for file in *.php
do
iconv -f cp1251 -t utf8 "$file"
done
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 83
这不起作用,因为iconv首先创建输出文件(因为文件已经存在,它会截断它),然后开始读取它的输入文件(现在是空的)。大多数程序都以这种方式运行。
为输出创建一个新的临时文件,然后将其移动到位。
for file in *.php
do
iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
mv -f "$file.new" "$file"
done
Run Code Online (Sandbox Code Playgroud)
如果您的平台iconv没有-o,您可以使用 shell 重定向来达到相同的效果。
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
mv -f "$file.new" "$file"
done
Run Code Online (Sandbox Code Playgroud)
Colin Watson 的sponge实用程序(包含在Joey Hess 的 moreutils 中)自动执行此操作:
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done
Run Code Online (Sandbox Code Playgroud)
这个答案不仅适用iconv于任何过滤程序。一些特殊情况值得一提:
-p可以-i选择替换文件。grep,tr,sed 's/long input text/shorter text/'),你就像生活危险的是,你可能要真正修改文件的地方(其他的解决方案在这里提到的创建新的输出文件并将其移动到最后,因此如果命令因任何原因中断,原始数据不会改变)。man*_*ork 66
另一种方法是recode,它使用 libiconv 库进行一些转换。它的行为是用输出替换输入文件,所以这将起作用:
for file in *.php
do
recode cp1251..utf8 "$file"
done
Run Code Online (Sandbox Code Playgroud)
由于recode接受多个输入文件作为参数,您可以避免for循环:
recode cp1251..utf8 *.php
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
62535 次 |
| 最近记录: |