Nano Hash - криптовалюты, майнинг, программирование

Замена недопустимых символов в имени файла на тире с помощью AppleScript

Моя цель - создать сервис в Automator с использованием AppleScript или Javascript, который заменяет все недопустимые символы в выбранном имени файла ()[\\/:"*?<>|]+_ и пробелы на тире (-) и делает имя файла строчным.


  • Удачи с этим. 02.05.2018
  • Похоже на забавный проект, где ты застрял? 02.05.2018

Ответы:


1

Замена недопустимых символов в имени файла / папки может быть достигнута с помощью сценария Bash Shell в вашем сервисе Automator.

Следующие шаги описывают, как этого добиться:

Настройка Automator

  1. Запускать автомат
  2. Введите ⌘N или выберите File> New в строке меню.
  3. Выберите Service и нажмите Choose
  4. В верхней части области холста настройте его параметры следующим образом:

    введите описание изображения здесь

  5. Выберите Library вверху панели / столбца слева:

    • В поле поиска введите: Получить элементы Select Finder и перетащите действие Get Select Finder items в область холста.

    • В поле поиска введите: Run Shell и перетащите действие Run Shell Script в область холста.

  6. Настройте верхнюю часть действия Run Shell Script следующим образом:

    введите описание изображения здесь

  7. Добавьте следующий сценарий Bash в основную область действия Run shell Script:

    #!/usr/bin/env bash
    
    # The following characters are considered impermissible in a basename:
    #
    #  - Left Square Bracket:   [
    #  - Right Square Bracket:  ]
    #  - Left Parenthesis:      (
    #  - Reverse Solidus:       \
    #  - Colon:                 :
    #  - Quotation Mark         "
    #  - Single Quotation Mark  '
    #  - Asterisk               *
    #  - Question Mark          ?
    #  - Less-than Sign         <
    #  - Greater-than Sign      >
    #  - Vertical Line          |
    #  - Plus Sign              +
    #  - Space Character
    #  - UnderScore             _
    #
    #  1. Sed is utilized for character replacement therefore characters listed
    #     in the bracket expression [...] must be escaped as necessary.
    #  2. Any forward slashes `/` in the basename are substituted by default with
    #     a Colon `:` at the shell level - so it's unnecessary to search for them.
    #
    declare -r IMPERMISSIBLE_CHARS="[][()\\:\"'*?<>|+_ ]"
    declare -r REPLACEMENT_STRING="-"
    
    # Obtain the POSIX path of each selected item in the `Finder`. Input must
    # passed to this script via a preceding `Get Selected Finder Items` action
    # in an Automator Services workflow.
    declare selected_items=("$@")
    
    declare -a sorted_paths
    declare -a numbered_paths
    
    # Prefix the POSIX path depth level to itself to aid sorting.
    for ((i = 0; i < "${#selected_items[@]}"; i++)); do
      numbered_paths+=("$(echo "${selected_items[$i]}" | \
          awk -F "/" '{ print NF-1, $0 }')")
    done
    
    # Sort each POSIX path in an array by descending order of its depth.
    # This ensures deeper paths are renamed before shallower paths.
    IFS=$'\n' read -rd '' -a sorted_paths <<<  \
        "$(printf "%s\\n" "${numbered_paths[@]}" | sort -rn )"
    
    
    # Logic to perform replacement of impermissible characters in a path basename.
    # @param: {Array} - POSIX paths sorted by depth in descending order.
    renameBaseName() {
      local paths=("$@") new_basename new_path
    
      for path in "${paths[@]}"; do
    
        # Remove numerical prefix from each $path.
        path="$(sed -E "s/^[0-9]+ //" <<< "$path")"
    
        # Replaces impermissible characters in path basename
        # and subsitutes uppercase characters with lowercase.
        new_basename="$(sed "s/$IMPERMISSIBLE_CHARS/$REPLACEMENT_STRING/g" <<< \
            "$(basename "${path}")" | tr "[:upper:]" "[:lower:]")"
    
        # Concatenate original dirname and new basename to form new path.
        new_path="$(dirname "${path}")"/"$new_basename"
    
        # Only rename the item when:
        # - New path does not already exist to prevent data loss.
        # - New basename length is less than or equal to 255 characters.
        if ! [ -e "$new_path" ] && [[ ${#new_basename} -le 255 ]]; then
          mv -n "$path" "$new_path"
        fi
      done
    }
    
    renameBaseName "${sorted_paths[@]}"
    
  8. Завершенная область холста вашей службы / рабочего процесса Automator должна теперь выглядеть примерно так:

    введите описание изображения здесь

  9. Введите ⌘S или выберите File> Save в строке меню. Назовем файл Replace Impermissible Chars.


Запуск службы:

  1. В Finder:

    • Select a single file or folder and then ctrl+click to show the contextual menu
    • Выберите службу Replace Impermissible Chars в контекстном меню, чтобы запустить ее.
  2. Либо в Finder:

    • Select multiple files and/or folders and then ctrl+click to show the contextual menu
    • Выберите службу Replace Impermissible Chars в контекстном меню, чтобы запустить ее.

Примечания:

  1. Finder позволяет запускать Службу одновременно с 1000 выбранными файлами / папками.

  2. Если это первая созданная вами служба Automator, вам возможно (если я правильно запомнил!) Потребуется перезагрузить компьютер, чтобы она стала доступной через контекстное всплывающее меню.

  3. Сценарий Bash Shell не заменяет недопустимые символы в имени файла / папки, если выполняется одно из следующих двух условий:

    • Если имя файла / папки уже существует, которое совпадает с именем результирующего нового имени файла / папки. Например: Допустим, у нас есть файл с именем hello-world.txt и в той же папке файл с именем hello?world.txt. Если мы запустим Сервис на hello?world.txt, его имя не будет исправлено / изменено, так как это потенциально может перезаписать hello-world.txt файл, который уже существует.

    • Если результирующее имя файла составляет >= до 255 символов. Это, конечно, может произойти только в том случае, если вы измените значение REPLACEMENT_STRING (в сценарии Bash / Shell) на несколько символов, а не только на один дефис -.

16.05.2018
  • Большое спасибо, РобК! Все работает как и ожидалось. 21.05.2018

  • 2

    Это довольно просто с помощью Regular Expression и Foundation Framework, соединенного с AppleScriptObjC.

    use AppleScript version "2.4" -- Yosemite (10.10) or later
    use scripting additions
    
    use framework "Foundation"
    
    set fileName to "New(Foo)*aBcd<B|r.ext"
    
    set nsFileName to current application's NSString's stringWithString:fileName
    set nsLowerCaseFileName to nsFileName's lowercaseString()
    set trimmedFileName to (nsLowerCaseFileName's stringByReplacingOccurrencesOfString:"[()[\\/:\"*?<>|]+_]" withString:"-" options:(current application's NSRegularExpressionSearch) range:{location:0, |length|:nsLowerCaseFileName's |length|()}) as text
    display dialog trimmedFileName
    
    02.05.2018
  • Я пытаюсь внедрить ваш код в рабочий процесс, а затем запустить службу через контекстное меню, выбрав имя flie. Но после завершения кода я получаю уведомление: new-foo - abcd-b-r.ext 02.05.2018
  • Это строка display dialog. Просто удали его. 02.05.2018
  • Но имя файла не меняется. 02.05.2018
  • Если вы получили new-foo--abcd-b-r.ext, имя изменилось. Результат есть в trimmedFileName. Это просто пример, fileName жестко запрограммирован. Вы должны встроить код в свою среду. 02.05.2018
  • Это должен быть принятый ответ. Работает отлично! Есть ли способ упростить его и удалить часть кода в нижнем регистре? 29.12.2020
  • @JordanHe Удалите строку lowercaseString() и в следующей строке замените nsLowerCaseFileName's на nsFileName's 29.12.2020

  • 3

    Здесь два отличных решения. Но поскольку каждая проблема обычно имеет множество решений, я предлагаю другое:

        property alphabet : "abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        --------------------------------------------------------------------------------
        rename from "HELLO World+Foo(\"Bar\")new.ext"
        --------------------------------------------------------------------------------
        ### HANDLERS
        #
        # rename from:
        #   Receives a text string and processes it for invalid characters, which
        #   get replaced with the specified replacement string (default: "-"),
        #   returning the result
        to rename from filename given disallowed:¬
            invalidCharSet as text : "[()[\\/:\"*?<>|]+_] ", replaceWith:¬
            replacementStr as text : "-"
            local filename
            local invalidCharSet, replacementStr
    
            set my text item delimiters to {replacementStr} & ¬
                the characters of the invalidCharSet
    
            text items of the filename as text
    
            makeLowercase(the result)
        end rename
    
    
        # makeLowercase():
        #   Receives a text string as input and returns the string formatted as
        #   lowercase text
        to makeLowercase(str as text)
            local str
    
            set my text item delimiters to ""
    
            if str = "" then return ""
    
            set [firstLetter, otherLetters] to [¬
                the first character, ¬
                the rest of the characters] of str
    
    
            tell the firstLetter to if ¬
                it is "-" or ¬
                it is not in the alphabet then ¬
                return it & my makeLowercase(the otherLetters)
    
            considering case
                set x to (offset of the firstLetter in the alphabet) mod 27
            end considering
    
            return character x of the alphabet & my makeLowercase(the otherLetters)
        end makeLowercase
    

    Этот код можно использовать в действии Запустить AppleScript Automator, поместив rename from... в обработчик on run {input, parameters}, а остальную часть кода - за его пределы. Он может следовать за действием, которое предоставляет ему список файлов в Finder, или он может получать свои входные данные непосредственно из входных данных рабочего процесса, если он запускается как Служба .

        property alphabet : "abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
        on run {input, parameters}
            tell application "Finder" to repeat with f in input
                set the name of f to (rename from f)
            end repeat
        end run
    
        to rename from ...
            .
            .
        end rename
    
        to makeLowercase(str as text)
            .
            .
        end makeLowercase
    
    14.06.2018
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


    © 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование