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

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

Удачи с этим.

Lajos Arpad 02.05.2018 14:30

Похоже на забавный проект, где ты застрял?

sniperd 02.05.2018 15:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
1 278
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это довольно просто с помощью 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

Я пытаюсь внедрить ваш код в рабочий процесс, а затем запустить службу через контекстное меню, выбрав имя flie. Но после завершения кода я получаю уведомление: new-foo - abcd-b-r.ext

Yuri 02.05.2018 18:40

Это линия display dialog. Просто удали его.

vadian 02.05.2018 18:41

Но имя файла не меняется.

Yuri 02.05.2018 18:44

Если вы получаете new-foo--abcd-b-r.ext, имя имеет изменилось. Результат - в trimmedFileName. Это просто пример, fileName жестко запрограммирован. Вы должны встроить код в свою среду.

vadian 02.05.2018 18:45

Это должен быть принятый ответ. Работает отлично! Есть ли способ упростить его и убрать «строчную» часть кода?

Jordan He 29.12.2020 19:20

@JordanHe Удалите строку lowercaseString() и в следующей строке замените nsLowerCaseFileName's на nsFileName's

vadian 29.12.2020 19:35
Ответ принят как подходящий

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

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

Настройка Automator

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

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

    • В поле поиска введите: Get Select Finder items и перетащите действие 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:

    • Выберите файл или папку Один, а затем ctrl + click, чтобы отобразить контекстное меню.
    • Выберите сервис Replace Impermissible Chars в контекстном меню, чтобы запустить его.
  2. В качестве альтернативы в Finder:

    • Выберите файлы и / или папки несколько, а затем ctrl + click, чтобы отобразить контекстное меню.
    • Выберите сервис 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) на более чем один символ вместо одного дефиса -.

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

Yuri 21.05.2018 16:29

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

    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Автомат, помещая 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

Другие вопросы по теме