Скажем, у меня есть несколько переменных в сценарии оболочки (например, в zsh):
FOLDER_1, FOLDER_2, etc.
Эти переменные относятся к папкам по убыванию /
. Например, если у меня есть путь/home/me/stuff/items
переменные будут:
FOLDER_1='home'
FOLDER_2='me'
FOLDER_3='stuff'
Теперь скажите, что я хочу построить соответствующий путь путем объединения переменных. Один из возможных способов - построить путь следующим образом:
PATH=$FOLDER_1/$FOLDER_2/$FOLDER_3/
Тем не менее, скажем, что некоторые переменные FOLDER_i
идут с косой чертой, в то время как другие не (и мы не знаем, какие), например
FOLDER_1='home'
FOLDER_2='stuff/'
FOLDER_3='items'
Мой вопрос: как я мог построить путь надежно? (например, избегая двойных слешей и добавляя их там, где они должны быть).
Я подумал, что один из способов сделать это - добавить /
всегда между парами переменных, а затем удалить любые дубликаты с помощью sed
, но я не могу заставить его работать (я не уверен, что я /
правильно обрабатываю sed
).
Кроме того, я изобретаю колесо ? (т. е. есть ли встроенный, который это уже делает?).
Наконец, если переменные находятся в массиве , например FOLDERS
, возможно ли сделать это без зацикливания? (или, альтернативно, циклично, но не зная, сколько FOLDERS
их в массиве).
источник
%
метод работает для одиночной косой черты, упомянутой в квесте. Для обслуживания, когда есть несколько слэшей,${parts[@]%%/*}
работает. Вот ссылка на немного больше информации о проблеме косой черты: Что означают двойные косые черты в пути UNIX? Является ли 'cd dir / subdir // действует .../*
в данном случае это не ноль или более косых черт , а скорее косая черта, за которой следует любое количество символов. Это означает, что если ваш путь начинается с косой черты, результатом будет пустая строка!extglob
(с регулярным выражением) ..shopt -s extglob; ${parts[@]%%/+(/)}
...Простой ответ - перестать беспокоиться и любить множественные слэши. Несколько косых черт имеют тот же эффект, что и одна косая черта (за исключением того, что путь, начинающийся с,
//
имеет различное значение в нескольких системах; я могу назвать только слои эмуляции unix в Windows). Именно так и было задумано, и возможность собирать имена файлов, не беспокоясь о множественных слешах, была основной частью этого проектного решения.Чтобы объединить элементы массива, в zsh вы можете использовать
j
флаг расширения параметра .Вы можете раздавить дублирующую косую черту, пока вы на ней, но это чисто косметическое средство.
В ksh и bash вы можете объединить массив, используя первый символ
$IFS
в качестве разделителя. Затем вы можете сжать дубликаты. В bash вам нужно будетshopt -s extglob
включить глобусы ksh в последней строке фрагмента ниже.источник
Как
sed
у вас не работает? Попробуйтеsed 's|/\+|/|g'
после объединения илиsed 's|/||g'
до.источник
bash 4
введено расширенное глобирование, которое позволяет сопоставлять регулярные выражения при подстановке параметров${var....}
... По умолчанию оно отключено. Чтобы включить его для вашего скрипта, просто установите параметр оболочки extglob ...Предполагая, что $ dir ==
/home/me/////////stuff//items
Результирующее значение $ dir
Вот несколько примеров с do-s и not-s - расширенная глобализация Bash
источник