【问题标题】:How to exclude subfolders containing "[xxx] - ( yy) - [xxx]"如何排除包含“[xxx] - (yy) - [xxx]”的子文件夹
【发布时间】:2017-11-21 01:05:16
【问题描述】:

我有这样组织的文件夹:

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

我需要:

  • 进入每个Folderx解压缩其中包含的文件
  • 如果提取的文件未成功提取,则记录日志
  • 将提取的文件移动到另一个文件夹
  • 如果提取的文件未成功移动,则记录 如果有任何失败,我不想要这个过程。

我一开始就想到了:

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 -type d”替换为“find .-maxdepth 1”或使用数组等,但总有一些失败。

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

$ find . -type d

我得到这个结果:

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

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

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

我从来没有找到避免在每个空间分割路径的方法......

有什么提示吗?

提前致谢

【问题讨论】:

  • 很抱歉布局不佳,我想我在这里使用它很糟糕......
  • 谢谢,我又试了一次,我想它会更好......引用效果不太好......或者至少我没有使用它应该在这里......

标签: bash parsing directory subdirectory


【解决方案1】:

由于您的目录包含空格,因此会对它们执行分词(在每一行 find 返回)。在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 选项给出目标目录。

或者在 bash 4+ 中,您可以使用 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

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

【讨论】:

  • 你好,非常感谢,“find . -type d | while read D; do”让我上路了,它不起作用(尽管脚本仍然缺少一些东西。
【解决方案2】:

感谢 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

【讨论】:

  • 我面临的另一个挑战是脚本会尝试访问“.”。以及其他子文件夹,我花了一段时间才明白,通过将其分配给我的 if "&& [[ ! "$D" =~ ^\.$ ]]" 来管理它可以很容易地解决...
  • 改用find . -mindepth 1 -type d。它只会返回子目录,跳过.
  • 并且always quote your variables。例如,写:cd "$BASE/$D"unzip -u "$z"echo "Success - $D/$z"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
相关资源
最近更新 更多