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

如何递归处理目录下所有.dat文件,仅保留前两列并替换原文件?

递归处理所有.dat文件,仅保留前两列并替换原文件

我来帮你搞定这个递归处理.dat文件的问题~你之前的命令没成功主要有几个小问题,我给你拆解下,再给你靠谱的解决方案:

你原来命令的问题

  1. find的写法不对:find *.dat只会查找当前目录下的.dat文件,没法递归子目录,应该用find . -type f -name "*.dat"来遍历所有子目录里的.dat文件
  2. 变量解析冲突:你命令里的$1在双引号中会被shell当成第一个位置参数解析,而不是awk的第一个字段,导致awk没法正确识别要输出的列
  3. 直接覆盖原文件有风险:如果直接用awk ... > "$file",shell会先清空原文件再让awk读取,最后得到的是空文件,必须用临时文件中转

正确的递归处理命令

推荐用find结合sh -c的方式,安全又高效,还能避免上述问题:

find . -type f -name "*.dat" -exec sh -c '
  # 循环处理每个找到的.dat文件
  for file do
    # 用awk提取前两列,输出到临时文件
    awk "{print \$1, \$2}" "$file" > "$file.tmp"
    # 如果awk执行成功,就用临时文件替换原文件
    if [ $? -eq 0 ]; then
      mv "$file.tmp" "$file"
    else
      # 处理失败的话删除临时文件,避免残留
      rm "$file.tmp"
      echo "处理失败:$file"
    fi
  done
' sh {} +

命令说明

  • find . -type f -name "*.dat":递归查找当前目录及所有子目录下的.dat格式文件
  • -exec sh -c '...' sh {} +:把找到的所有文件传给后面的shell脚本批量处理,{} +会把文件列表作为参数传给脚本里的$@(也就是循环里的file)
  • 用$file.tmp作为临时文件,确保原文件不会被意外清空,只有当awk处理成功时才替换原文件
  • 额外加了错误处理,如果某个文件处理失败,会提示并清理临时文件

更简洁的版本(如果不需要错误提示)

如果你的环境比较可靠,也可以用更短的写法:

find . -type f -name "*.dat" -exec sh -c '
  for file do
    awk "{print \$1, \$2}" "$file" > "$file.tmp" && mv "$file.tmp" "$file"
  done
' sh {} +

重要提醒

操作前一定要备份文件! 虽然上面的命令用了临时文件做中转,但万一出现意外(比如磁盘空间不足、脚本中断),还是可能导致数据丢失,建议先复制一份文件目录再执行命令。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:22:09