我的根文件夹结构如下:
My Family - Holiday My Birthday[15.11] Name-Name[1] Name1 Name2 ...
现在,我希望每个包含.info
文件的文件夹都移动到另一个目录。
这是我的代码:
#!/bin/sh
for folder in *
do
echo $folder
if [ -e "$folder/*.info" ]
then
echo $folder
mv $folder ./Finished
fi
done
回声仅用于测试。
我发现只要if
失败,名称中的非转义字符就会出现。我该如何解决这个问题?
答案 0 :(得分:6)
Bash希望你引用变量。
#!/bin/bash
if [[ "$1" = "-v" ]]; then
Verbose=true
vopt="-v"
shift
else
Verbose=false
vopt=""
fi
for folder in *; do
$Verbose && printf "%s" "$folder"
if [[ -e "$folder/*.info" ]]; then
if mv "$vopt" "$folder" ./Finished/; then
$Verbose && echo -n " ... done"
fi
fi
$Verbose && echo ""
done
请注意,使用斜杠结束目标目录是个好主意。这样,如果由于某种原因Finished
目录消失,你将得到一个错误,而不是默默地将第一个$文件夹重命名为Finished,然后将所有其他匹配移动到第一个匹配。
另请注意,我正在使用printf
进行某些调试输出,以防您的$folder
之一以连字符开头。
更新#1 :您现在已使用-v
选项控制调试。
更新#2 :我刚刚意识到你正在检查*.info
的确切存在。注意:
ghoti@pc ~$ mkdir foo
ghoti@pc ~$ touch foo/\*.info
ghoti@pc ~$ ls -la foo
total 0
-rw-r--r-- 1 ghoti ghoti 0 8 Aug 07:45 *.info
drwxr-xr-x 3 ghoti ghoti 102 8 Aug 07:45 .
drwx------+ 10 ghoti ghoti 340 8 Aug 07:44 ..
ghoti@pc ~$ [[ -e "foo/*.info" ]] && echo yes
yes
ghoti@pc ~$ mv foo/\*.info foo/bar.info
ghoti@pc ~$ [[ -e "foo/*.info" ]] && echo yes
ghoti@pc ~$
如果您真正想要找到的是“任何以.info结尾的文件”,那么[[ -e
就不是了。在我更多地研究这个答案之前请确认一下。 :)
更新#3 :
如果文件夹包含任何.info文件,这是一个可以移动文件夹的版本。请注意,不 grep ls
的输出。
[ghoti@pc ~/tmp1]$ cat doit
#!/bin/bash
if [[ "$1" = "-v" ]]; then
Verbose=true
vopt="-v"
shift
else
Verbose=false
vopt=""
fi
for folder in *; do
infofile="$(
if [[ -d "$folder" ]]; then
cd "$folder"
for file in *.info; do
if [[ -f "$file" ]]; then
echo "$file"
break
fi
done
fi
)"
if [[ -f "$folder/$infofile" ]]; then
mv "$vopt" "$folder" ./Finished/
elif $Verbose; then
printf "%s ... skipped\n" "$folder"
fi
done
[ghoti@pc ~/tmp1]$ find . -print
.
./doit
./baz
./foo
./foo/bar.info
./Finished
[ghoti@pc ~/tmp1]$ ./doit -v
Finished ... skipped
baz ... skipped
doit ... skipped
foo -> ./Finished/foo
[ghoti@pc ~/tmp1]$
答案 1 :(得分:3)
主要问题是您无法使用test -e *.info
。您可以解析ls的输出以检查文件。解析ls存在问题,但它们的重要性远远低于很多人的解决方案。如果您不允许文件名中的换行符,则以下内容应该有效:
#!/bin/sh
for dir in *; do
if ls -f "$dir" | grep -q '\.info$'; then
mv "$dir" ./Finished
fi
done
请注意,任何文件名都没有嵌入换行符是必不可少的,因为这会错误地识别名为foo.info\nbar
的文件,就像有一个名为foo.info
的文件一样。实际上,这不太可能是一个重大问题。如果这是一个问题,你不会想要使用shell,尽管你可以这样做:
#!/bin/sh
for dir in *; do
for f in "$dir"/*; do
case "$f" in
*.info) mv "$dir" ./Finished; break;;
esac
done
done
答案 2 :(得分:-1)
试试这个:
PATH_TO_FOLDER="/YOUR_FOLDER"
for f in `ls $PATH_TO_FOLDER`;
do
# Check filename
if [ $(echo $f | grep -Ec ".info$") -ne 1 ]
then
echo "We don't care"
else
## move the file
fi
done