#string #bash #shell #divide
#строка #bash #оболочка #разделить
Вопрос:
Я не силен в написании сценариев оболочки bash в Ubuntu, поэтому мне нужна ваша помощь.
Проблема в том…
Мы используем Perforce для SCM.
Я пытаюсь получить каталоги из //Development/
ветвей.
До этого времени все было хорошо.
Но теперь я больше не могу разделять ветви пробелами из-за таких ветвей, как следующие (обратите внимание на встроенный пробел):
//Development/graphic/release/Unity Provider
Нам нужна каждая ветвь в отдельной строке, начинающаяся с //Development
, но я всегда получаю следующий результат (обратите внимание на нежелательный разрыв строки):
// Разработка / графика / релиз / Единство Поставщик
Как я могу это исправить?
Пожалуйста, помогите мне. Спасибо.
Ниже приведен пример однострочной строки:
//Development/graphic/release/CM //Development/graphic/release/GManager //Development/graphic/release/Notification //Development/graphic/release/Core //Development/graphic/release/Provider //Development/graphic/release/WH //Development/graphic/release/Accessory //Development/graphic/release/Unity Provider //Development/graphic/release/tipManager
И я хочу получить результирующую строку, как показано ниже (имя каждой ветви в отдельной строке):
//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager
Я также хочу сохранить результаты в переменной списка.
Например, list[0]
должен содержать . //Development/graphic/release/CM
Комментарии:
1. каков ваш ожидаемый результат?
2. Как вы определяете каталоги? Вы не можете переименовать каталог в
Unity-Provider
, чтобы избежать мучений с пробелами в имени пути?
Ответ №1:
Я предполагаю, что:
- вы хотите разделить входную строку на отдельные пути на основе подстрок, начинающихся с
//[Development/]
, либо в начале строки, либо, если внутри, перед одним пробелом. - независимо от того, содержат ли строки между
//[Development/]
экземплярами пробелы или нет.
str='//Development/graphic/release/CM //Development/graphic/release/GManager //Development/graphic/release/Notification //Development/graphic/release/Core //Development/graphic/release/Provider //Development/graphic/release/WH //Development/graphic/release/Accessory //Development/graphic/release/Unity Provider //Development/graphic/release/tipManager'
echo "$str" | sed 's# (//)#'$'n''1#g'
Приведенное выше должно работать с любой POSIX-совместимой sed
реализацией.
Чтобы записать выходные данные в переменной, используйте подстановку команд:
result=$(echo "$str" | sed 's# (//)#'$'n''1#g')
Если затем вы хотите обработать результат построчно:
while read -r path; do echo "$path"; done <<<"$result"
Объяснение sed
команды:
#
был — произвольно — выбран в качестве разделителя дляsed
команды ‘ss
(подстановка строки), чтобы упростить сопоставление/
символов (обычно/
используется в качестве разделителя, что потребовало/
экземпляров в регулярном выражении и заменяющей строке).(//)
совпадает//
, если перед ним стоит пробел, т.Е. Внутри строки.'$'n''
эффективно вставляет новую строку (n
) в строку замены, используя кавычки ANSI C (требуется для совместимости с OSX; в Linux простоn
подойдет).1
вставляет 1-ю (и единственную) группу захвата из регулярного выражения, т.е,//
g
гарантирует, что соответствие является глобальным, т. Е. Заменяются все подстроки, соответствующие регулярному выражению.
Результат:
//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager
Комментарии:
1. Спасибо за вашу помощь, но я не могу использовать опцию -E в sed cmd. Я думаю, что эта ос redhat
2. @user3754723: Понятно. Я только что обновил свой ответ, чтобы сделать его совместимым с POSIX, что должно сработать для вас — дайте мне знать, если это не так.
3. Большое вам спасибо, и… У меня есть еще один вопрос …:) Как я могу сохранить его в переменной? список =
echo "$str" | sed 's# (//)#'$'n''1#g'
Это не работает, я хочу. Я хочу сохранить его в list.4. @user3754723 Добро пожаловать; повторный захват выходных данных в переменной: см. Мое обновление.
5. Ну, мне все равно нужно получить тот же результат: (
for element in $result do echo $element done
Извините, я не могу красиво прокомментировать, используя новую строку 🙁
Ответ №2:
Используйте переменную разделителя внутренних полей (IFS) для разрыва в новой строке вместо пробела.
Это хорошо объясняет: http://mindspill.net/computing/linux-notes/using-the-bash-ifs-variable-to-make-for-loops-split-with-non-whitespace-characters/
Пример, взятый по ссылке выше:
#!/bin/bash
IFS=$','
vals='/mnt,/var/lib/vmware/Virtual Machines,/dev,/proc,/sys,/tmp,/usr/portage,/var/tmp'
for i in $vals;
do echo $i;
done
unset IFS
Комментарии:
1. Повторная терминология: новые строки также являются формой пробела (пробела). Пример ввода OP представляет собой однострочную строку , поэтому разделение на новые строки не применяется.
Ответ №3:
Вы также можете попробовать эту команду awk,
$ awk -v RS=" //" '{gsub (/^D/,"//D");}1' file
//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager
Комментарии:
1. Нет, нет ~ я хочу сделать это, как показано ниже: // Разработка / графика / релиз / CM // Разработка / графика / релиз / GManager // Разработка / графика / релиз / Уведомление // Разработка / графика / релиз / Ядро // Разработка / графика / релиз / Поставщик // Разработка /графический / релиз / WH // Разработка / графический / релиз / Аксессуар // Разработка / графический / релиз / Поставщик единства // Разработка / графический / релиз / tipManager
2. опубликуйте приведенный выше комментарий в своем вопросе.