解压缩未知名称文件的Bash脚本

时间:2013-09-24 19:04:02

标签: bash pattern-matching unzip glob

我有一个文件夹,在rsync之后会有一个zip文件夹。我想将其解压缩到自己的文件夹(如果zip是L155.zip,将其内容解压缩到L155文件夹)。问题是我之前不知道它的名字(虽然我知道它将是“letter-number-number-number”),所以我必须将一个未知文件解压缩到它的未知文件夹,这将自动完成。

命令“unzip *”(或解压缩* .zip)在终端中工作,但不在脚本中工作。 这些是通过终端逐个工作的命令,但不能在脚本中工作。

#!/bin/bash
unzip * #also tried .zip and /path/to/file/*  when script is on different folder
i=$(ls | head -1)
y=${i:0:4}
mkdir $y
unzip * -d $y

首先我解压缩文件,然后通过ls读取第一个提取文件的名称并将其保存在变量中。我取前4个字符并用它创建一个目录然后再​​将文件解压缩到该特定文件夹。

完成第一次解压缩后的整个过程,是因为.zip里面的文件都是以zip已有的名字开头的,所以如果L155.ZIP是zip,里面的文件是L155 * * * .txt的。

zip文件位于/path/to/file/NAME.zip。 当我运行脚本时,我得到如下错误:

unzip: cannot find or open /path/to/file/*.ZIP
unzip: cannot find or open /path/to/file//*.ZIP.zip
unzip: cannot find or open /path/to/file//*.ZIP.ZIP. No zipfiles found. 
mkdir: cannot create directory 'data': File exists data 
unzip: cannot find or open data, data.zip or data.ZIP.

5 个答案:

答案 0 :(得分:2)

原始回答

假设foo.zip包含文件夹foo,您只需运行

即可
#!/bin/bash
unzip \*.zip \*

然后将其作为bash auto-unzip.sh运行。

如果您想将这些文件提取到另一个文件夹中,那么我会将上面的内容修改为

#!/bin/bash
cp *.zip /home/user
cd /home/user
unzip \*.zip \*
rm *.zip

当然,您可以从存储所有zip文件的文件夹中运行。


另一个答案

另一个“简单”修复是获取dtrx(也可以在Ubuntu repos中使用,可能用于其他发行版)。这会将每个*.zip文件提取到自己的文件夹中。因此,如果您想要将数据放在不同的文件夹中,我会按照第二个示例进行更改:

#!/bin/bash
cp *.zip /home/user
cd /home/user
dtrx *.zip
rm *.zip

答案 1 :(得分:1)

如果该文件夹只包含扩展名为.zip的文件,您可以使用basename工具提取不带扩展名的名称:

BASE=$(basename *.zip .zip)

如果有多个文件与*.zip匹配,则会产生错误消息。

为了清楚这里的问题,我们假设zip文件不包含文件夹结构。如果确实如此,就没有问题;您可以使用unzip将其提取到子文件夹中。如果您的zipfile包含松散文件,并且您想将它们提取到子文件夹中,则仅需要以下内容。

有了这个警告,以下内容应该有效:

#!/bin/bash
DIR=${1:-.}
BASE=$(basename "$DIR/"*.zip .zip 2>/dev/null) ||
  { echo More than one zipfile >> /dev/stderr; exit 1; }
if [[ $BASE = "*" ]]; then
  echo No zipfile found >> /dev/stderr
  exit 1
fi
mkdir -p "$DIR/$BASE" ||
  { echo Could not create $DIR/$BASE >> /dev/stderr; exit 1; }
unzip "$DIR/$BASE.zip" -d "$DIR/$BASE"

将它放在一个文件中(任何地方),称之为unzipper.shchmod a+x。然后你可以这样称呼它:

/path/to/unzipper.sh /path/to/data_directory

答案 2 :(得分:1)

for zfile in $(find . -maxdepth 1 -type f -name "*.zip")
do
  fn=$(echo ${zfile:2:4})  # this will give you the filename without .zip extension
  mkdir -p "$fn"  
  unzip "$zfile" -d "$fn"
done

答案 3 :(得分:1)

我会尝试以下方法。

for i in *.[Zz][Ii][Pp]; do
    DIRECTORY=$(basename "$i" .zip)
    DIRECTORY=$(basename "$DIRECTORY" .ZIP)
    unzip "$i" -d "$DIRECTORY"
done

如上所述,basename程序从提供的文件名中删除指示的后缀.zip

我已将其编辑为不区分大小写。 <{1}}和.zip都将被识别。

答案 4 :(得分:0)

我一直使用的简单的一个班轮

$ for file in `ls *.zip`; do unzip $file -d `echo $file | cut -d . -f 1`; done