bash (unix shell scripting) 解压多个 zip 文件,按照 zip 文件名重命名解压后的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25432321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
(unix shell scripting) Unzip multiple zip files, rename unzipped file following zip file name
提问by Thuan Nguyen
I have multiple zip files like this example:
我有多个 zip 文件,如下例所示:
759198298412.zip
----i love you.pdf
----forever and one.txt
----today and tomorrow.docs
48891721241592__5123.zip
----whatever it is.pdf
5717273_616.zip
----igotit.txt
----thank you very much.mp3
I am trying to make a script to unzip the zip files, and rename the unzipped files to the zip file name. like this output:
我正在尝试制作一个脚本来解压缩 zip 文件,并将解压缩的文件重命名为 zip 文件名。像这样的输出:
759198298412.pdf
759198298412.txt
759198298412.docs
48891721241592__5123.pdf
5717273_616.txt
5717273_616mp3
I found this script below, but it doesn't work for me because my files have space and i have multiple files in a zip file.
我在下面找到了这个脚本,但它对我不起作用,因为我的文件有空间并且我在一个 zip 文件中有多个文件。
for i in *.zip
do
n=$(unzip -lqq $i | awk '{print $NF}')
e=${n#*.}
unzip $i && mv $n ${i%%_*}".$e"
done
Please help! thank you
请帮忙!谢谢你
回答by Etan Reisner
for i in *.zip; do
mkdir "$i-dir"
cd "$i-dir"
unzip "../$i"
for j in *; do
mv "$j" "$i.${j##*.}"
done
cd ..
done
If dropping everything after the first underscore in the file name is important than the mv line should be:
如果删除文件名中第一个下划线之后的所有内容很重要,那么 mv 行应该是:
mv "$j" "${i%%_*}.${j##*.}"
And to have that dropping work even when no underscore is present in the zip file name use:
并且即使在 zip 文件名中不存在下划线的情况下也要进行删除工作,请使用:
i=${i%.zip}; mv "$j" "${i%%_*}.${j##*.}"
And to keep the files all in the top-level directory prefix ../
to the mv
target filename.
并将文件全部保留../
在mv
目标文件名的顶级目录前缀中。
回答by Beggarman
A few small changes:
一些小的变化:
- Quote variables to deal with the spaces in file names.
- Use
unzip -Z -1
to get a listing of the files in the archive to avoid using awk (which is printing just the final part of names with spaces). - Since
unzip -Z -1
splits records by line, we set the IFS to '\n' so records split properly. - Replace the underscore in the move to a dot so .zip extension is removed.
- 引用变量来处理文件名中的空格。
- 使用
unzip -Z -1
来获取文件的列表中存档,以避免使用AWK(这是打印的名字与空间只有最后一部分)。 - 由于
unzip -Z -1
按行拆分记录,我们将 IFS 设置为 '\n' 以便记录正确拆分。 - 将移动中的下划线替换为点,以便删除 .zip 扩展名。
New script is:
新脚本是:
IFS=$'\n'
for i in *.zip
do
for n in $(unzip -Z -1 "$i"); do
echo "$i - $n"
e=${n#*.}
unzip "$i" "$n" && mv "$n" ${i%%.*}".$e"
done
done
Note that this script assumes you've only got one of each file extension in your zip. If that's not true, you'll need to handle duplicate files in some fashion.
请注意,此脚本假定您的 zip 文件中只有每个文件扩展名之一。如果不是这样,您将需要以某种方式处理重复文件。
Output after running:
运行后输出:
48891721241592__5123.pdf
48891721241592__5123.zip
759198298412.docs
759198298412.pdf
759198298412.txt
759198298412.zip
回答by scht_r
for zip in *.zip; do
zip_filename="${zip%%.*}"
unzip "${zip}" -d "${zip_filename}-dir"
for file in "${zip_filename}-dir"/*.*; do
extension="${file##*.}"
new_name="${zip_filename}.${extension}"
mv "${file}" "${new_name}"
done
rmdir "${zip_filename}-dir"
# delete the zip file
# rm "${zip}"
done
The script basically just unzips the files to a new temporary directory, it then renames all the files in the new directory and moves them out of the directory, and finally it deletes the temporary directory.
该脚本基本上只是将文件解压缩到一个新的临时目录,然后重命名新目录中的所有文件并将它们移出目录,最后删除临时目录。