我有一个旧的.bat文件,我需要在我的QNAP上运行。我需要递归地为每个文件创建文件夹(基于文件名),然后将文件移动到该文件夹。
这是旧的.bat:
@echo off
for %%a in (*.*) do (md "%%~na" 2>nul
move "%%a" "%%~na"
)
答案 0 :(得分:1)
如果我正确理解.bat语法,这应该基本相同:
#!/bin/sh
for a in *
do
[ ! -f "$a" ] && continue # skip anything that is not a regular file
dirname="${a%.*}" # trim off the last suffix
mkdir -p "$dirname" && mv -i "$a" "$dirname/"
done
与原始文件一样,此脚本仅处理当前目录中的文件。如果你需要处理当前目录及其所有预先存在的子目录(这是我将如何理解"递归地")它会变得有点复杂,因为脚本必须继续以深度优先的方式避免尝试将文件推入无限深的子子目录。
在这种情况下,需要开发一个不同的解决方案,最有可能使用find
命令来收集文件名。默认情况下,find
命令是递归的:它将自动处理指定的目录及其所有子目录,除非您具体告诉它不要。所以这是一个递归版本,可以处理任何目录中的任意数量的文件:
#!/bin/sh
# FIXME: needs more protection against unusual filename characters
find . -type f -depth | while read a
do
dirname="${a%.*}" # trim off the last suffix
mkdir -p "$dirname" && mv -i "$a" "$dirname/"
done
但是有一个小问题:如果文件名包含换行符,则可能无法正确处理该文件名。但是如果你的文件名称中只包含表现良好的字符,那就足够了。