一堆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个文件的情况下以递归方式正确循环遍历目录?
答案 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脚本中的循环更快或更慢。只是处理事情的另一种方式。