2010-04-25 49 views
6

我已经看到了循环来解压缩目录中的所有zip文件。不过,我跑在此之前,我宁愿知道我快要运行会工作的时候:shell循环可以解压缩目录中的所有文件吗?

for i in dir; do cd $i; unzip '*.zip'; rm -rf *.zip; cd ..; done 

基本上我希望它看起来在“目录”输出中看到所有文件夹,每个目录cd进入它,解压缩所有的zip压缩文件,然后删除它们,然后再回来再做,直到没有更多。

这是我应该做的一个单一的命令,或者我应该考虑在Perl中这样做吗?

+1

你好,欢迎来到StackOverflow。为使您的代码更具可读性,请使用代码标签 – 2010-04-25 16:43:22

+1

作为您的信息,您可以使用cd - 回到以前的目录。 – Aif 2010-04-25 16:47:48

+0

@帕特里克完成:) – DVK 2010-04-26 00:45:44

回答

1

部分地进行了测试:

find . -type d -exec sh -c "cd \"{}\" ; unzip \"*.zip\" ; rm \"*.zip\" " \; 

执行cd/unzip/rm链为每一个子目录。

+0

到目前为止,这个作品中,其他答案不能像“文件夹名称与空间”一样,但不能删除.zip存档。 – helpwithshell 2010-04-25 17:01:28

+0

我认为你必须使用'find ... | xargs -0 ...'来处理空白,或者逃脱的引号做这个工作吗? – Anycorn 2010-04-25 17:06:18

+0

最后我能够修改你的命令行到: 找。 -name“* .zip”-exec sh -c“rm -rf \”{} \“”\; 删除所有剩余的.zip压缩文件。谢谢 – helpwithshell 2010-04-25 17:18:40

1

使用*来得到当前目录的内容:

for i in *; do cd "$i"; ...etc... ; done 

你也应该确保的东西是试图cd到前一个目录。

if [ -d "$i" ]; then ...etc... ; fi 

你也应仔细检查解压缩操作删除压缩文件之前成功:在bash此如下完成。不需要使用递归强制删除来删除单个文件。

我认为这是推动一个单一的行合理的限制。把它放到一个shell脚本中并在多行上格式化。

2

你应该一般很好。只需在循环中加上前缀echo的前缀进行调试就可以告诉你变量是如何扩展的。您也可以始终使用rm -i,而不是让rm继续使用-f

您的unzip调用中的单引号将只解压缩名为*.zip的文件,即*不会扩展。改为使用双引号(或根本没有引号)。

您的循环现在假设所有目录$i都直接在当前目录下。更通用的解决方案是使用目录堆栈(pushdpopd);

for i in $dir; do 
    pushd $i 
    unzip *.zip 
    rm -rf *.zip 
    popd 
done 
+0

我不得不改变第一个从我在迪尔为我在*,它unziped的东西,但有问题的文件,其中包含空格的名称。 – helpwithshell 2010-04-25 16:54:31

+0

@help:我隐含地认为'dir'是一个变量,当它不是我的例子是错误的。现在修复并假定'dir'是一个保存目录列表的变量。 – 2010-04-25 17:02:48

2

的几点加到其他人所说:

  • 如果你把单引号内的参数,如在'*.zip',外壳不会做野卡扩展并解压缩会尝试处理存档这就是所谓的*.zip
  • 如果您只想删除单个文件,请不要使用-r作为rm的参数。这是不必要的危险,因为任何递归删除的子目录可能不会被打算。
  • 您应该检查的unzip返回代码且仅当解压缩成功删除的zip文件(例如,你可以说​​,甚至用一个明确的for循环来处理压缩文件逐个)
0

当你想知道,如果一个事情会工作,但提防它的破坏性后果,做一些在同一时间:

确保你得到正确的文件:

for i in dir; do cd $i; echo $i; cd ..; done 

确保您可以解压缩文件在删除文件之前:

for i in dir; do cd $i; unzip '*.zip'; cd ..; done 

而且,你做充分的蒙蒂之前,让您的目录的备份。

相关问题