Попытка добавить все файлы из текущего каталога в архив и назвать выходной файл в соответствии с определенным именем/расширением файла, которое было добавлено.
По сути, когда добавляется файл с расширением .exe, мне бы хотелось, чтобы имя архива совпадало с именем этого файла, при условии, что он всего один и есть хотя бы один .exe.
Foo.exe -> Foo.7z
Вот сценарий, который у меня есть на данный момент 7z a archive.7z *.* -x!*.sh
решение1
set -- *.exe
сохраняет имена файлов, соответствующие *.exe
позиционным параметрам, если только нет совпадений. В случае отсутствия совпадений результат зависит от оболочки (см. началоэтот ответ); в оболочке POSIX вы получаете литеральную *.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" …
)
Я использовал подоболочку, поэтому set
это не влияет на позиционные параметры основной оболочки.Цитирование важно.
Примечания:
- Решение позволяет сопоставить соответствие с каталогом.Любой каталог также является файлом.
- Вы написали "добавить все файлы", а затем использовали
*.* -x!*.sh
. Я не собираюсь придираться, говоря, что исключение противоречит "всем файлам". Хотя есть проблемы:-x!*.sh
следует заключить в кавычки, чтобы оболочка никогда не расширялась*
. Строка должна быть заключена в одинарные кавычки, поскольку некоторые оболочки расширяются!
даже в двойных кавычках.*.*
может означать «все файлы» в Windows (по крайней мерес некоторыми инструментами), но в оболочке Linux точка строго соответствует точке.*
поскольку шаблон генерации имени файла ближе к «все файлы»,еще не "все файлы".
- Решение склонно кТОКТОУ. Вероятно, содержимое вашего каталога не меняется "случайно", и решение сработает. Если каталог не статичен, то может потребоваться создать архив с временным именем, составить список его содержимого и проанализировать его, чтобы узнать, что
.exe
(если таковое имелось) попало в архив, и, наконец, переименовать архив соответствующим образом. - Помните, что имена файлов в Linux в целом чувствительны к регистру; инструменты, работающие с именами файлов, также чувствительны к регистру. Обычно
set -- *.exe
не обнаруживаетFOO.EXE
. В некоторых оболочках вы можете настроить это поведение (например, исследоватьshopt -s nocaseglob
в Bash); тогда вы захотите использовать${1%[eE][xX][eE]}7z
для правильной работы сEXE
,Exe
или любым другим вариантом во время преобразования имени.