You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Bash脚本转换文件内容大小写时文件内容被清空的问题

解决Bash脚本转换大小写时清空文件的问题

嘿,我太懂这种崩溃的感觉了!你大概率是踩了Bash脚本里一个超级常见的坑——直接用重定向覆盖原文件导致的内容清空。

问题根源

当你写出类似这样的代码时:

tr 'a-z' 'A-Z' $file > $file

Bash的执行顺序是先处理重定向操作:它会先打开$file并清空里面的内容,然后才会去读取这个已经空了的文件,传给tr命令处理。最后tr输出空内容,再写入已经被清空的文件,结果自然就是所有文件都变成空的了。

正确的解决方案

下面给你几个可靠的解决方法,按通用性排序:

1. 用临时文件中转(最稳妥,跨平台)

这是最安全的做法,通过临时文件先保存转换后的内容,再替换原文件:

#!/bin/bash
# 替换成你的目标目录
target_dir="/path/to/your/target/dir"

# 遍历目录下的所有条目
for file in "$target_dir"/*; do
    # 跳过目录,只处理普通文件
    [ -f "$file" ] || continue
    
    # 创建一个安全的临时文件
    temp_file=$(mktemp)
    
    # 将转换后的内容写入临时文件
    tr 'a-z' 'A-Z' < "$file" > "$temp_file"
    
    # 用临时文件覆盖原文件
    mv "$temp_file" "$file"
done

mktemp会自动生成一个唯一的临时文件名,避免多个脚本同时运行时的冲突,非常稳妥。

2. 使用sed的原地编辑功能

GNU sed(Linux默认)支持-i选项实现原地修改文件,BSD sed(比如macOS上的)需要加一个空后缀-i '':

#!/bin/bash
target_dir="/path/to/your/target/dir"

for file in "$target_dir"/*; do
    [ -f "$file" ] || continue
    
    # GNU sed 版本(Linux)
    sed -i 's/[a-z]/\U&/g' "$file"
    
    # 如果是 macOS/BSD 系统,替换成下面这句
    # sed -i '' 's/[a-z]/\U&/g' "$file"
done

这里的\U&是sed的语法:\U表示把后续字符转成大写,&代表匹配到的原字符,g表示全局替换所有小写字符。

3. 使用sponge工具(更简洁)

sponge是moreutils工具包中的工具,它会先把所有输入内容读入内存,再写入目标文件,完美避免了重定向顺序的问题。如果你的系统没有这个工具,可以用包管理器安装(比如apt install moreutils或brew install moreutils):

#!/bin/bash
target_dir="/path/to/your/target/dir"

for file in "$target_dir"/*; do
    [ -f "$file" ] || continue
    
    tr 'a-z' 'A-Z' < "$file" | sponge "$file"
done

额外注意事项

  • 如果需要处理隐藏文件(以.开头的文件),$target_dir/*不会匹配到,你可以改成for file in "$target_dir"/.* "$target_dir"/*,然后再过滤掉.和..这两个特殊目录。
  • 所有变量都要用双引号包裹,避免文件名含空格、特殊字符时出现错误。
  • 测试脚本时,建议先拿几个备份文件试试,避免意外丢失数据!

内容的提问来源于stack exchange,提问作者JesusR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:15:25