我有一个循环,需要它来忽略空目录。
for i in */*/
do
cd "$i"
mv ./*.py ..
cd -
rm -r "$i"
done
我可以添加什么来使它忽略空目录?
我有这个,但我想要更简单的
x=$(shopt -s nullglob dotglob; echo "$i"/*)
(( ${#x} )) || continue
我可以添加什么使其忽略空目录?
Bash没有用于测试目录是否为空的基元运算符。在您的情况下,最好的选择可能是测试路径名扩展是否与中的任何文件匹配。这是你已经在考虑的,尽管我会用不同的方式写。
一般来说,我也会避免更改工作目录。如果必须更改目录,请考虑在子shell中进行更改,这样您只需要让子shell终止即可恢复到原始工作目录。当脚本的不同部分需要不同的shell选项时,使用子shell也是一种很好的方法。
我可能会这样写你的剧本:
#!/bin/bash
shopt -s nullglob dotglob
for i in */*/; do
anyfiles=( "$i"/* )
if [[ ${#anyfiles[@]} -ne 0 ]]; then
# Process nonempty directory "$i"
# If there are any Python files within then move them to the parent directory
pyfiles=( "$i"/*.py )
if [[ ${#pyfiles[@]} -ne 0 ]]; then
mv "${pyfiles[@]}" "$(dirname "$i")"
fi
# Remove directory "$i" and any remaining contents
rm -r "$i"
fi
done
如果您希望将其作为更大脚本的一部分,那么您可以将从shopt
到末尾的所有内容都放在子shell中,以限制shopt
的范围。
或者,您可以通过使用循环跳过将目录内容捕获到显式变量中来稍微简化它,但要牺牲一些清晰度:
#!/bin/bash
shopt -s nullglob dotglob
for i in */*/; do
for anyfile in "$i"/*; do
# Process nonempty directory "$i"
# If there are any Python files within then move them to the parent directory
for pyfile in "$i"/*.py; do
mv "$i"/*.py "$(dirname "$i")"
break
done
# Remove directory "$i" and any remaining contents
rm -r "$i"
break
done
done
在这种情况下,每个内部循环的末尾都包含一个无条件的break
,因此最多将执行一次迭代。