Bash - 递归重命名“.tmp”文件

时间:2015-02-19 15:05:01

标签: bash

一堆Word&当进程在完成之前终止时,Excel文档正在服务器上移动。因此,我们留下了几个具有.tmp扩展名的完美文件,我们需要将这些文件重命名为相应的.xlsx或.docx扩展名。

这是我目前在Bash中执行此操作的代码:

#!/bin/sh

for i in "$(find . -type f -name *.tmp)"; do
    ft="$(file "$i")"
    case "$(file "$i")" in
        "$i: Microsoft Word 2007+")
            mv "$i" "${i%.tmp}.docx"
            ;;
        "$i: Microsoft Excel 2007+")
            mv "$i" "${i%.tmp}.xlsx"
            ;;
    esac
done

似乎虽然这是递归搜索,但它只做1个文件。如果找到初始匹配,则不会继续重命名其余文件。如何在没有一次只执行1个文件的情况下以递归方式正确循环遍历目录?

2 个答案:

答案 0 :(得分:2)

尝试这样的find命令:

while IFS= read -r -d '' i; do
    ft="$(file "$i")"
    case "$ft" in
        "$i: Microsoft Word 2007+")
            mv "$i" "${i%.tmp}.docx"
            ;;
        "$i: Microsoft Excel 2007+")
            mv "$i" "${i%.tmp}.xlsx"
            ;;
    esac
done < <(find . -type f -name '*.tmp' -print0)
  • 使用<(...)称为进程替换以在此处运行find命令
  • 引用find
  • 中的文件名模式
  • 使用-print0获取由空字符分隔的find输出,以允许文件名中的空格/换行符
  • 使用IFS=-d ''读取空分隔文件名

答案 1 :(得分:1)

我也建议使用find。我会在find

的两次传递中执行此操作
find . -type f -name \*.tmp \
 -exec sh -c 'file "{}" | grep -q "Microsoft Word 2007"' \; \
 -exec sh -c 'f="{}"; echo mv "$f" "${f%.tmp}.docx"' \;

find . -type f -name \*.tmp \
 -exec sh -c 'file "{}" | grep -q "Microsoft Excel 2007"' \; \
 -exec sh -c 'f="{}"; echo mv "$f" "${f%.tmp}.xlsx"' \;

为了便于阅读,将拆分行。

find的每个实例都会搜索tmp文件,然后使用-exec来测试find的输出。这与您在shell脚本中的while循环中执行此操作的方式类似,只是从find内部启动它。我们将管道用于grep而不是您的案例陈述。

第二个-exec只有在第一个返回“true”(即grep -q ...找到某些内容)时才会运行,并在一个小的shell实例中执行重命名。

我没有对此进行分析,看它是否比shell脚本中的循环更快或更慢。只是处理事情的另一种方式。