Вы довольно озадачены тем, как работает цитирование в оболочке. Первое правило: кавычки идут вокруг данных, а не в данных. Например, вы используете:
course="'/path/to/311/folder/$2'"
...
mv $file $course
Когда вы устанавливаете course
таким образом, двойные кавычки обрабатываются как синтаксис оболочки (т. Е. Они изменяют то, что между ними анализируется), но одинарные кавычки сохраняются как часть значения переменной и будут после этого рассматриваться как данные. Когда вы используете эту переменную в команде mv
, она на самом деле ищет каталог, буквально названный одинарной кавычкой, и под этим каталогом, называемым «путь» и т. Д. Вместо этого, просто поместите соответствующие кавычки для того, как вы хотите, чтобы он анализировался в этой точке , а затем двойные кавычки вокруг переменной при ее использовании (для предотвращения вероятного нежелательного расщепления слов и расширения по шаблону). Как это:
course="/path/to/311/folder/$2"
...
mv "$file" "$course" # This needs more work -- see below
Кроме того, где у вас есть:
mdfind 'kMDItemUserTags='$1'' -onlyin /Users/user/Downloads
это не имеет никакого смысла. У вас есть раздел с одинарными кавычками, 'kMDItemUserTags='
, где кавычки не действуют вообще (одинарные кавычки подавляют все специальные значения, которые имеют символы, например $
, вводящие подстановку переменных, но там нет символов с специальные значения, поэтому нет причины для кавычек), за которыми следуют $
без двойных кавычек вокруг него, что означает, что некоторые специальные символы (пробелы и подстановочные знаки) в его значении получат специальный синтаксический анализ (который вам, вероятно, не нужен), за которым следует строка в одинарных кавычках нулевой длины, ''
, которая разбирается на абсолютно ничего. Вы хотите часть $1
в двойных кавычках; некоторые люди также включают остальную часть строки в раздел в двойных кавычках, что никак не влияет. Фактически, кроме части $2
(и пробелов между параметрами), вы можете заключать в кавычки или нет, как вы хотите. Таким образом, любой из них будет работать эквивалентно:
mdfind kMDItemUserTags="$1" -onlyin /Users/user/Downloads
mdfind "kMDItemUserTags=$1" -onlyin /Users/user/Downloads
mdfind "kMDItemUserTags=$1" '-onlyin' '/Users/user/Downloads'
mdfind 'kMDItemUserTags'="$1" '-'"only"'in' /'Users'/'user'/'Down'loads
...etc
Хорошо, следующая проблема: парсинг вывода из mdfind
из серии символов в отдельные пути к файлам. Это на самом деле сложно. Если вы поместите двойные кавычки вокруг изменяющейся строки, она будет рассматриваться как один длинный путь к файлу, который содержит в себе некоторые символы новой строки (что совершенно законно, но не то, что вы хотите). Если вы не заключите его в двойные кавычки, он будет разбит на отдельные пути к файлам на основе пробелов (не только переводы строк, но также пробелы и табуляции - и пробелы являются общими в именах файлов MacOS), и все, что выглядит как подстановочный знак, будет расширено до списка совпадающих имен файлов. Это может привести к хаосу.
Решение: есть один символ, который не может встречаться в пути к файлу, ASCII NULL (код символа 0), и mdfind -0
выведет свой список, разделенный нулевыми символами. Вы не можете поместить результат в переменную оболочки (они также не могут содержать нули), но вы можете передать его через конвейер, скажем, xargs -0
, который (благодаря опции -0
) будет анализировать обнуляет как разделители и строит команды из результатов. Есть одна немного хитрая вещь: вы хотите, чтобы xargs
поместил пути к файлам, которые он получает в середине списка аргументов, в mv
, а не в конце, как это обычно делается. Опция -J
позволяет указать, куда добавлять аргументы. Я также предложу две меры безопасности: опция -p
для xargs
заставляет ее спрашивать перед фактическим выполнением команды (используйте ее, по крайней мере, до тех пор, пока вы не будете уверены, что она работает правильно), и опция -n
для mv
, который говорит, что не следует перезаписывать существующие файлы в случае конфликта имен. Результат примерно такой:
mdfind -0 kMDItemUserTags="$1" -onlyin /Users/user/Downloads | xargs -0 -p -J% mv -n % "$course"