如何排除包含“[xxx] - (yy) - [xxx]”的子文件夹

How to exclude subfolders containing "[xxx] - ( yy) - [xxx]"

我的文件夹是这样组织的:

Folder1
[xxx] - ( aa) - [xxx]
 1.zip
 2.zip
Folder2
[xxx] - ( bb ) - [xxx]
 11.zip
 22.zip

我需要:

我一开始就想到了:

for D in `find . -type d`
do
    cd $D
    echo "$(pwd)"
    for z in *.zip; do
        unzip -u $z
        echo "File: " $z; 
        if [ $? -eq 0 ]
            then
                echo "Successfully created file"
            else
                echo "Could not create file" >&2
        fi; 
    done
done

我尝试了很多方法,例如用 "find . -maxdepth 1" 替换 "find . -maxdepth 1 -type d" 或使用数组等,但总有一些失败。

我认为我的主要问题是当我尝试时:

$ find . -type d

我得到这个结果:

Folder1
Folder1/[xxx] - ( aa) - [xxx]
Folder2
Folder2/[xxx] - ( bb ) - [xxx]

但是当我在我的脚本中使用相同的命令时,它会像这样解析它:

Folder1
[xxx]
-
( 
a
)
-
[xxx]
Folder2
[xxx]
-
(
bb
)
-
[xxx]

我从来没有找到避免在每个 space...

处分割路径的方法

有什么提示吗?

提前致谢

由于您的目录包含空格,因此对它们执行分词(在每一行 find returns)。请参阅 bash pitfalls 页面上对这种情况(for 循环文件列表)的很好解释。

编写最外层 for 循环的方法之一如下:

find . -type d | while read D; do
    cd "$D"
    ...
done

对于更简单的操作,另一种方法是仅使用 find-execdir 操作,如下所示:

find . -name '*.zip' -execdir unzip -u '{}' \;

注意我们使用execdir动作执行文件目录中的命令,而不是exec执行当前目录中的命令,因为unzip 在当前目录中提取,除非通过 -d 选项给出目标目录。

或者在bash4+中,可以使用glob递归展开:

shopt -s globstar
for z in ./**/*.zip; do
    dir="$(dirname "$z")"
    cd "$dir"
    unzip -u "$z" && echo "OK" || echo "Failed to extract $z"
done

另外,不要忘记(几乎)总是引用你的变量

感谢 randomir,主要问题现已解决!多谢!

这是我目前所做的:

BASE=/path/to/my/stuff

find . -type d | while read D
do
    EXTRACTED=0
    if [[ ! "$D" =~ ^(.*)"[" ]] && [[ ! "$D" =~ ^\.$ ]]
        then cd $BASE/$D
            for z in *.zip
            do
            unzip -u $z
                if [ $? -eq 0 ]
                    then
                        echo "ZIP SUCCESS - " $D"/"$z >> $BASE/details.log
                    else
                        echo "ZIP FAILED - " $D"/"$z >> $BASE/details.log
                        EXTRACTED=1
                fi; 
            done
        unrar x -o+ *.rar 
        if [ $? -eq 0 ]
            then
                echo "RAR SUCCESS - " $D >> $BASE/details.log
            else
                echo "RAR FAILED - " $D >> $BASE/details.log
                EXTRACTED=1
        fi; 

        if [ $EXTRACTED -eq 0 ]
            then
                echo "SUCCESS - " $D >> $BASE/main.log
            else
                echo "FAILED - " $D >> $BASE/main.log
        fi; 
    fi;
done