Мой проект
Я создаю сценарий оболочки bash для выполнения из терминала. Его целью является архивирование множества папок проекта. Каждая папка соответствует установленной номенклатуре [YYYY.MM.DD] - Medium - Client - Project name - details--details - JobNumber
. Например: [2006.02.01] - Print - Development - Appeal I - Kids Art Show Insert - D0601-11
. Эти проекты в настоящее время находятся в одной папке. Я хочу отсортировать их по папкам по имени клиента. Есть 7 (внутренних) клиентов, поэтому я использую следующий скрипт оболочки:
#!/bin/bash
# Go to the Completed Projects folder.
cd /Volumes/communications/Projects/Completed\ Projects/
# Find a folder with a specified string (e.g. "Academics") in its name.
# Move (not copy) the folder to its corresponding sub-folder of the Archived Projects folder. (e.g. /Academics)
for folder in *; do
if [[ -d "$folder" ]]; then
if [[ "$folder" == *Academics* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Academics/
fi
elif [[ "$folder" == *Admissions* ]]; then
echo "Archiving $folder to Archived Projects → Admissions...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Admissions/
fi
elif [[ "$folder" == *Alumni* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Alumni/
fi
elif [[ "$folder" == *Communications* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Communications/
fi
elif [[ "$folder" == *Development* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Development/
fi
elif [[ "$folder" == *President* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/President/
fi
elif [[ "$folder" == *Student\ Life* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Student\ Life/
fi
else #Folders that don't match the pattern prompt the use to move them by hand.
echo "$folder does not have a Department name. Move it by
done
Моя проблема
Мой скрипт будет неправильно анализировать и подавать проект с именем [2006.03.01] - Print - Development - Academics and Accreditation - D0601-08
. Это прочитало бы "Академики" прежде, чем это когда-либо попадало в условное для клиента "Развитие". В результате это будут файлы в «Академики». И мне придется забрать его обратно вручную!
Преимущество моей системы
Мои коллеги и я были очень внимательны к нашей номенклатуре (описано выше). Я знаю, что имя Клиента находится между 2 и 3 дефисами.
Мой вопрос
Как использовать преимущество моей системы для решения моей проблемы? Я хочу, чтобы этот скрипт совпадал только с той частью имени папки, которая идет после первых двух дефисов и до третьего дефиса, т. Е. Я хочу, чтобы только этот скрипт выполнял поиск в «поле» клиента в имени папки. Я продолжаю думать "регулярные выражения", но не знаю, как их реализовать.
Примечание. Я предпочитаю, чтобы решение дополняло мой текущий сценарий, а не заменяло его. Я пришел к этому через @patrix на этом сайте, и его идея обошла некоторые ошибки.
источник
*- Academics -*
?Ответы:
Есть несколько способов сделать это с
bash
друзьями (вы могли бы действительно вырубить себя, используяsed
илиawk
). Довольно простой способ - использоватьcut
имя папкиЭто
$(echo $(echo ... ))
ленивый подход, чтобы избавиться от начального / конечного пространства (потомуcut
что не поддерживает разделители с несколькими символами).Если вы хотите покончить с собой,
sed
вы можете использоватьвместо
cut
. Это работает, только если имя целевой папки не содержит-
самого себя.Вместо сопоставления с образцом вы также можете использовать функцию оболочки для инкапсуляции большей части сложности.
источник
Как насчет использования awk с опцией разделителя полей -F и разделения поля дефисом. Тогда получите третье поле.
ОБНОВИТЬ
Я обновил код, чтобы использовать результат, возвращенный из awk, для размещения папки назначения. Это экономит много кода. А также использовал разделитель «-», как указал Ян в комментариях.
Я также добавил / "$ folder" в конце перемещения, чтобы сама папка была перемещена. Вы можете изменить это, если это не то, что вы хотите, удалив «$ folder» в конце команды mv.
Вы также можете провести перекрестную проверку по массиву из 7 имен, так что будут перемещены только те папки, которые соответствуют. (Вы можете вставить инструкцию else, где это необходимо)
источник
awk
это определенно способ пойти, если это должно остатьсяbash
.' - '
вместо просто'-'
Если вы можете изучать bash, вы, безусловно, сможете выучить лучший язык, такой как Ruby, чтобы решить эту проблему.
В том, что я публикую, есть масса возможностей для улучшения, но вот несколько базовых Ruby, которые сделают вашу переклассификацию для вас. Некоторые преимущества этого кода Ruby перед вашим кодом bash:
client
полей и автоматически перемещает их в соответствии с предпочитаемой вами схемой архивирования.И, конечно, если вы спросите меня, это бесконечно более читабельно и расширяемо. Если вы можете изучать bash, Ruby - это очень сложная задача, и вы обнаружите, что с ней вы можете автоматизировать лучше, чем с bash.
Я пытался держаться ближе к тому, как работает ваш удар, чтобы он выглядел знакомым. Как вы можете видеть, это немного более кратко, чем этот удар.
источник
chmod +x <file name>
. Теперь просто введите имя файла, и он запустится. Эта волшебная первая строка!#/usr/bin/env ruby
указывает ОС запускать скрипт с использованием Ruby.details--details
Раздел колеблется в широких пределах из папки в папку. Он часто включает в себя специальные символы, такие как[ ] -
. @IanC.