尝试将当前目录中的所有文件添加到存档中,并根据添加的特定文件名/扩展名命名输出文件。
本质上,当添加带有 .exe 扩展名的文件时,我希望存档名称与该文件相同,假设只有一个且至少有一个 .exe。
Foo.exe->Foo.7z
这是我目前拥有的脚本 7z a archive.7z *.* -x!*.sh
答案1
set -- *.exe
将匹配的文件名存储*.exe
为位置参数,除非没有匹配。如果没有匹配,结果取决于 shell(参见这个答案); 在 POSIX shell 中,您将获得文字*.exe
字符串作为第一个也是唯一的位置参数。
如果您确定只有一个匹配项,则无需测试任何内容。如果您不确定,则:
- 检查是否
$#
扩展为1
([ "$#" -eq 1 ]
), - 检查所指文件是否存在(
[ -e "$1"]
)。
那么你要找的名字是$1
。要翻译Foo.exe
成Foo.7z
你需要消除exe
并添加7z
(${1%exe}7z
)。
该代码片段如下:
(
set -- *.exe
# here validate $# and/or $1 if necessary
7z a "${1%exe}7z" …
)
我使用了子shell,因此set
不会影响主shell的位置参数。引用很重要。
笔记:
- 该解决方案允许匹配成为目录。任何目录也是一个文件。
- 您写了“添加所有文件”,然后使用了
*.* -x!*.sh
。我不会吹毛求疵地说排除与“所有文件”相矛盾。但是存在问题:-x!*.sh
应该用引号引起来,这样 shell 就不会扩展*
。字符串应该用单引号引起来,因为有些 shell!
甚至在双引号中也会扩展。*.*
可能意味着 Windows 中的“所有文件”(至少使用一些工具),但在 Linux shell 中,点严格匹配一个点。*
作为文件名生成模式更接近“所有文件”,仍然不是“所有文件”。
- 该解决方案容易托克托。您的目录内容可能不会“随机”更改,解决方案将有效。如果目录不是静态的,则可能需要创建一个具有临时名称的存档,列出其内容并进行解析以了解
.exe
存档中包含的内容(如果有),最后相应地重命名存档。 - 请记住,Linux 中的文件名通常区分大小写;处理文件名的工具也区分大小写。通常
set -- *.exe
不会检测FOO.EXE
。在某些 shell 中,您可以调整此行为(例如shopt -s nocaseglob
在 Bash 中调查);然后您需要使用${1%[eE][xX][eE]}7z
来正确处理EXE
,Exe
或名称转换期间的任何其他变体。