Noe*_*uli 3 shell bash function
我有数百个多个文件夹,其中包含数千个 zip 文件,这些文件包含嵌套在 zip 文件中,如下面三个所示
\n\nstart tree structure\n012016/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 2016-01\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 2016-01\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 DOC\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WONWA1\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WO1NWA1\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WO2016000001NWA1.xml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WO1NWA1.zip\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WO2NWA1\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WO2016000002NWA1_tr.xml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WO2NWA1.zip\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 2016-01.zip\n\nend tree structure\nRun Code Online (Sandbox Code Playgroud)\n\n我在下面创建了一个简短的脚本,它递归地检查文件夹和内容,如果找到任何 zip 文件,它就会提取内容,然后继续检查提取的文件夹的内容。
\n\n当我尝试运行下面的脚本时:
\n\nrecurse() {\n for i in "$1"/*;\n do\n currentItem="$i"\n extension="${currentItem##*.}"\n\n if [ -d "$i" ]; then\n #echo "dir: $i"\n recurse "$i"\n elif [ -f "$i" ]; then\n #echo "file: $i"\n #echo "ext: $extension"\n\n [[ ${extension} = +(sh|xslt|dtd|log|txt) ]] && break\n\n extractionDirectory=$(dirname $currentItem)/$(basename -s .zip $currentItem )\n\n [[ ${extension} = "zip" ]] && unzip -uq $currentItem -d "${extractionDirectory}"\n\n recurse ${extractionDirectory}\n fi\n done }\n recurse $PWD\nRun Code Online (Sandbox Code Playgroud)\n\n但是,当我运行上面的脚本时,我收到错误:
\n\n\n\n分段错误(核心转储)
\n
造成分段错误的原因有很多。最常见的低级原因是进程试图访问未定义的内存地址,即无效的指针取消引用。这通常是程序中的错误。
在这里,您正在运行一个 shell 程序。shell 是一种高级编程语言,没有指针,因此您的脚本不会导致无效的指针取消引用。
许多程序的调用堆栈空间有限,并且由于超出堆栈大小而导致分段错误。在大多数情况下,堆栈大小限制对于任何合理的数据来说都足够大,但无限递归可能会破坏堆栈。
在 bash 中,函数调用中的无限递归确实会导致分段错误。(dash 和 mksh 也是如此;ksh 和 zsh 更聪明,并且在 shell 级别应用最大函数调用嵌套深度,这样它们就不会出现段错误。)
您的脚本有几个错误。令您困扰的是,对于常规文件,您总是recurse在最后调用,而您显然只想对 zip 文件执行此操作。
当您的意思是 时,不要使用&&or 。写出你的意思就更清楚了;通过晦涩难懂来简洁并不是一个好主意,它在这里让你感到困扰。||if
if [[ ${extension} = "zip" ]]; then
unzip -uq $currentItem -d "${extractionDirectory}"
recurse ${extractionDirectory}
fi
Run Code Online (Sandbox Code Playgroud)
另一个错误是您在变量替换周围缺少双引号,因此您的程序将因包含空格(以及其他)的文件名而阻塞。始终在变量替换周围使用双引号,除非您知道需要将其省略。
使用参数扩展而不是调用basenameand dirname。处理特殊情况更容易(例如以 开头的文件名-)并且速度更快。
我碰巧发现的另一个错误是该模式+(sh|xslt|dtd|log|txt)显然意味着@(sh|xslt|dtd|log|txt)(匹配这些扩展名,而不是shsh等dtdtxtshdtd)。
case这是常规文件情况,为了清楚起见,修复并重写了上述错误:
case "$extension" in
sh|xslt|dtd|log|txt) break;;
zip)
extractionDirectory=$"{currentItem%.zip}"
unzip -uq "$currentItem" -d "${extractionDirectory}"
recurse "${extractionDirectory}"
esac
Run Code Online (Sandbox Code Playgroud)
请注意,我尚未验证逻辑或测试代码。这似乎是一种复杂的写作方式
find -type f -name '*.zip' -exec sh -c 'unzip -uq "$0" -d "${0%.zip}"' {} \;
Run Code Online (Sandbox Code Playgroud)