Я пишу bash-скрипт, который вызывает внешнюю программу, которая генерирует zip-файл в форме ########.zip, в котором '#'s# может быть любой десятичной цифрой. Невозможно предсказать, какими будут цифры.
До сих пор мне удавалось использовать регулярное выражение [0-9][0-9]*zip для таких вещей, как перемещение zip-файла и его распаковка. Однако теперь мне нужно добавить в архив txt-файл под именем каталога ########, где цифры совпадают с именем архива. Итак, если архив 12345678.zip, мне нужно добавить файл 12345678/foo.txt.
Единственный способ сделать это, как я вижу, - создать каталог «12345678» и скопировать туда файл, а затем добавить каталог в архив. Однако я не могу понять, как получить имя архива, чтобы создать каталог.
Лучшее, что я мог сделать, это использовать обратные кавычки, чтобы назначить вывод ls -l переменной, а затем проанализировать это, чтобы получить только часть имени файла. Но должен же быть более простой способ?
Я использую 7z в качестве утилиты zip, если это имеет значение.
Спасибо!
🤔 А знаете ли вы, что...
С Bash можно создавать скрипты, которые мониторят системные ресурсы и производительность.
То, что вы просите, - это не регулярное выражение, а «глобальное выражение». В частности, если вы хотите сопоставить любое количество цифр, это можно сделать с помощью функции bash, называемой расширенным подстановкой или «extglobs». Подробнее читайте на странице https://wiki.bash-hackers.org/syntax/pattern#extended_pattern_language.
#!/usr/bin/env bash
# ^^^^- NOT sh
shopt -s extglob
for f in +([[:digit:]]).zip; do
digits=${f%.zip}
mkdir -p "$digits"
echo hello >"$digits/foo.txt"
zip "$f" "$digits/foo.txt"
done
В расширение параметраdigits=${f%.zip}
мы убираем .zip
с конца имени файла и сохраняем остальное в переменной digits
.
Расширение вышеизложенного для работы во временном каталоге и очистки после себя:
#!/usr/bin/env bash
# ^^^^- NOT sh
shopt -s extglob
olddir=$PWD
for f in +([[:digit:]]).zip; do
digits=${f%.zip}
tempdir = "$(mktemp -d -t zipupdate.XXXXXX)"
(
cd "$tempdir" || exit
mkdir -p "$digits" || exit
echo hello >"$digits/foo.txt" || exit
zip "$olddir/$f" "$digits/foo.txt"
)
rm -rf "$tempdir"
done
Поскольку OP использует 7z
, мы можем использовать опцию rn
для переименования файла в архиве и, чтобы исключить необходимость создания/удаления временного подкаталога...
Настраивать:
$ 'rm' -rf zipdir
$ mkdir zipdir
$ cd zipdir
$ zipfile='12345678.zip'
$ digits = "${zipfile//.zip/}"
$ declare -p digits
declare -- digits = "12345678"
$ echo abc > sample.txt
$ echo def > foo.txt
Создайте/заполните ${zipfile}
sample.txt
и foo.txt
:
$ 7z a "${zipfile}" sample.txt foo.txt
... snip ...
Archive size: 158 bytes (1 KiB)
Everything is Ok
$ 7z l "${zipfile}"
... snip ...
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 ..... 4 4 foo.txt
2022-05-14 15:53:16 ..... 4 4 sample.txt
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 8 8 2 files
Теперь добавьте каталог ${digits}
в качестве префикса к foo.txt
:
$ 7z -- rn "${zipfile}" foo.txt "${digits}/foo.txt"
... snip ...
Archive size: 306 bytes (1 KiB)
Everything is Ok
$ 7z l "${zipfile}"
... snip ...
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 ..... 4 4 12345678/foo.txt
2022-05-14 15:53:16 ..... 4 4 sample.txt
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 8 8 2 files