В сценарии оболочки, Как передать переменную другое значение после выполнения одного задания?

Я пытаюсь создать скрипт, который увидит, существует ли каталог, и будет хранить все его содержимое под ним в соответствии с именем / контуром каталога.

Дальше я мог пойти –

#!/system/bin/sh -xv Z="$PWD/../WorkingDir"; T='320'; F='480'; I='540'; D='dark'; L='light'; P='play'; cd $Z; if [ -d $T/$D ]; then R=""$T"_"$D".zip"; else if [ -d $T/$L ]; then R=""$T"_"$L".zip"; else R="file.zip"; fi fi; for dir in */*/; do #Skip directories where the zip already exists [ -e "$dir"/"$R" ] || ( cd -- "$dir" && zip -0rq "$R" .) done 

Но это происходит –

 #!/system/bin/sh -xv ... . . if [ -d $T/$D ]; then R=""$T"_"$D".zip"; else if [ -d $T/$L ]; then R=""$T"_"$L".zip"; else R="file.zip"; fi fi; + [ -d 320/dark ] + R=320_dark.zip for dir in */*/; do #Skip directories where the zip already exists [ -e "$dir"/"$R" ] || ( cd -- "$dir" && zip -0rq "$R" .) done + [ -e 320/dark//320_dark.zip ] + cd -- 320/dark/ + zip -0rq 320_dark.zip . + [ -e 320/light//320_dark.zip ] + cd -- 320/light/ + zip -0rq 320_dark.zip . . . ...and so on.. , #!/system/bin/sh -xv ... . . if [ -d $T/$D ]; then R=""$T"_"$D".zip"; else if [ -d $T/$L ]; then R=""$T"_"$L".zip"; else R="file.zip"; fi fi; + [ -d 320/dark ] + R=320_dark.zip for dir in */*/; do #Skip directories where the zip already exists [ -e "$dir"/"$R" ] || ( cd -- "$dir" && zip -0rq "$R" .) done + [ -e 320/dark//320_dark.zip ] + cd -- 320/dark/ + zip -0rq 320_dark.zip . + [ -e 320/light//320_dark.zip ] + cd -- 320/light/ + zip -0rq 320_dark.zip . . . ...and so on.. , #!/system/bin/sh -xv ... . . if [ -d $T/$D ]; then R=""$T"_"$D".zip"; else if [ -d $T/$L ]; then R=""$T"_"$L".zip"; else R="file.zip"; fi fi; + [ -d 320/dark ] + R=320_dark.zip for dir in */*/; do #Skip directories where the zip already exists [ -e "$dir"/"$R" ] || ( cd -- "$dir" && zip -0rq "$R" .) done + [ -e 320/dark//320_dark.zip ] + cd -- 320/dark/ + zip -0rq 320_dark.zip . + [ -e 320/light//320_dark.zip ] + cd -- 320/light/ + zip -0rq 320_dark.zip . . . ...and so on.. 

Каждый файл получает то же имя ( 320_dark.zip в этом случае). Я хочу, чтобы он отличался (в зависимости от имени папки / пути) для каждого файла, который застегивается.

Я хотел –

 + [ -d 320/dark ] + R=320_dark.zip 

– каждый раз менять каждую папку. Как и должно быть 320_light.zip для пути папки 320/light .

Таким образом, последняя часть вывода будет –

 + [ -e 320/dark//320_dark.zip ] + cd -- 320/dark/ + zip -0rq 320_dark.zip . + [ -e 320/light//320_light.zip ] + cd -- 320/light/ + zip -0rq 320_light.zip . 

  • Ошибка распаковки, возможно ли восстановление?
  • Почтовая папка без указания пути к папке и требует только один аргумент
  • Возможно ли в unix выполнять поиск внутри zip-файлов
  • Как сжать файлы на основе даты файла
  • Команда для рекурсивного хеширования CRC (CRC32)
  • Понимание среды Linux Back-Slash и звездочки
  • Сжатие и удаление исходного каталога с ограниченным хранилищем
  • поиск содержимого файлов, упакованных в zip-файл
  • 2 Solutions collect form web for “В сценарии оболочки, Как передать переменную другое значение после выполнения одного задания?”

    Вот мое предложение, удаление однобуквенных переменных и изменение местоположения архива для согласованности:

     #!/system/bin/sh -xv cd "$PWD/../WorkingDir" compress() { # Detect only known dir names, convert slash to underscore local arch="$(echo $1 | sed -rne '/320\/(light|dark)/s@/@_@gp')" # Set a default value to the variable : ${arch:=file} # Only create a ZIP archive if not present in the parent directory # Note $PWD is evaluated *before* cd [ -f "${arch}.zip" ] || ( cd -- $1 && zip -0rq "${PWD}/${arch}.zip ." ) } for dir in */*/; do compress $dir done 

    Просто измените строку sed чтобы добавить то, что я назвал «известными именами каталогов».


    EDIT : добавление нескольких объяснений в соответствии с запросом OP.

    Скрипт проверяет условия до того, как каталоги zipping каждый раз, когда новый каталог найден в цикле for . Переменные также были устранены. Давайте проанализируем код.

    Основной цикл

     cd "$PWD/../WorkingDir" for dir in */*/; do # Ensures to select only directories compress $dir # compress runs some checks prior to compressing done 

    На самом деле не так много сказать об этом.

    Процедура compress

     local arch="$(echo $1 | sed -rne '/320\/(light|dark)/s@/@_@gp')" 

    $1 – аргумент, переданный в compressed , то есть каталог для проверки и сжатия. Что делает sed первую очередь ( '/320\/(light|dark)/' ), проверьте, имеет ли путь форму

     320/light 320/dark 

    и возвращает путь с косой чертой, преобразованной в символ подчеркивания: 's@/@_@g' . Использование знака at в качестве разделителя для удобства чтения, чтобы избежать слэш. Другими допустимыми обозначениями являются 's:/:_:g' или 's#/#_#g' или классический 's/\//_/g' . Обратите внимание, что слэш для преобразования экранируется с помощью анти-косой черты. Тем не менее, я считаю, что последняя форма менее читаема.

    Конечный p работает вместе с sed -n ; последний вариант в данном конкретном случае означает « не отгонять ничего, если не будет указано p когда будет найдено совпадение (т. е. в закрывающих косых чертах) ». Поэтому arch будет содержать путь с косой чертой, преобразованной в символ подчеркивания, если и только если в пути найдено регулярное выражение 320\/(light|dark) . В противном случае это ничего не даст, сделав arch пустой переменной.

    Опция -r – удобный способ сказать sed использовать канонические регулярные выражения, более читаемые. В противном случае вам нужно будет избежать символов скобок и труб. Я нахожу '/320\/(light|dark)/s@/@_@gp' более читаемым, чем '/320\/\(light\|dark\)/s@/@_@gp' или '/320\/\(light\|dark\)/s/\//_/gp' .

     : ${arch:=file} 

    Эта строка устанавливает arch в значение по умолчанию «файл», если оно пустое. Странная конструкция требуется, потому что только ${arch:=file} запускает синтаксическую ошибку. Двоеточие сообщает оболочке ничего не делать (:), но назначить arch значение, если оно пустое.

      [ -f "${arch}.zip" ] || ( cd -- $1 && zip -0rq "${PWD}/${arch}.zip ." ) 

    Здесь я использовал -f вместо -e потому что первый также проверяет файлы с нулевой длиной. Тест будет успешным только в том случае, если существует ZIP-архив и имеет ненулевую длину.

    Если в родительском (или текущем ) каталоге сценария нет файла архива, или если его размер равен нулю, тогда скрипт порождает под-оболочку, которая изменяется в каталог, переданный в качестве аргумента для compress и застегивания его содержимого. Обратите внимание, что переменные $1 и $PWD оцениваются до того, как подчиненная оболочка выполнит свои инструкции, то есть $PWD будет равна родительскому каталогу $Z в вашей начальной версии.

    Расширение фильтра

    Вы можете действовать следующим образом:

     sed -rne '/320\/(light|dark|play)/s@/@_@gp' 

    для проверки имен каталогов, таких как

     320/light 320/dark 320/play 

    Вы также можете рассмотреть /(320|480|540)\/(light|dark|play)/ , что дает вам 9 комбинаций или более общую форму /[0-9]+\/(light|dark|play)/ (любое число, за которым следуют косая черта и одна из « светлых », « темных » и « играющих ») или даже /[0-9]+\/\w+/ (любое число, за которым следует косая черта и слово aka [A-Za-z0-9_]+ ). Все зависит от того, насколько строго или широко вы хотите, чтобы фильтр был.

     #!/system/bin/sh -xv Z=/absolute/path/to/WorkingDir T=320 F=480 # ? I=540 # ? D=dark L=light P=play # ? cd $Z for dir in $Z*/*/; do if [ -d $Z/$T/$D ] && [ ! -f $T$D.zip ]; then zip -0rq $T$D.zip $dir; elif [ -d $Z/$T/$L ] && [ ! -f $T$L.zip ]; then # elif rules zip -0rq $T$L.zip $dir; # It's not very efficient to scale this up, but you could add more elif statements here. elif [ -d $Z/$F/$D ] && [ ! -f $F$D.zip]; then zip -0rq $F$D.zip $dir; # and so on.. else exit fi; done 

    Я думаю, что это все, что вам нужно. Сообщите мне, нужны ли какие-либо корректировки.

    Interesting Posts

    Добавить первый столбец в файл

    Использование nvidia-настроек над ssh

    Использование подстановочных доменов в sendmail

    Что касается создания и уничтожения конфиденциальных данных в системах linux / unix

    Есть ли у традиционных vi (not vim) поддержка больших файлов?

    Перенаправление порта

    В OSX vi, кажется, неожиданно возвращается 1, несмотря на отсутствие ошибки

    В vim, как отобразить «command-right» и «command-left» до начала строки и конца строки на mac?

    Почему Gnome или KDE не производят собственный дистрибутив (или другие проекты для настольных компьютеров, если на то пошло)?

    Архивируйте самый старый файл, где имена файлов указаны в соответствии с их меткой времени

    systemd-networkd не перезагрузит файл конфигурации виртуального сетевого интерфейса

    Имеются ли модули / драйверы linux в пространстве ядра или пространстве пользователя

    Какие отличные исходные ресурсы Emacs?

    Системный заказ загрузки не найден (безопасная загрузка не включена)

    Без Интернета через Wi-Fi

    Linux и Unix - лучшая ОС в мире.