Вот один из способов сделать это:
list=$(find /tmp /data/opr/ucansit/ -type d -name "???" -exec basename {} \;)
printf "%s\n" "${list[@]}"
Проблема здесь в /
в шаблоне в $ search_string
.
Поскольку /
не является буквенно-цифровым символом, он не считается «словом». Это означает, что шаблон \ path \>
не будет соответствовать / path
, поскольку перед /
нет границы слова.
Измените строку поиска на / path \>
(т.е. s ## $ search_string \> ## g
) вместо этого или используйте / path [^ 0- 9]
, или, с этими конкретными входными данными и строкой поиска, вы можете просто использовать s # $ search_string ## g
в качестве замены.
используйте эту команду, чтобы получить то, что вы хотите:
input_string = $ (echo $ input_string | sed "s # $ search_string \ b ## g")
sed
не заменяет \ b
означает границу слова, и вот его определение:
Метасимвол \ b - это привязка, например каретка и знак доллара. Он соответствует позиции, которая называется «границей слова». Это совпадение нулевой длины.
Есть три различных позиции, которые квалифицируются как границы слова:
- Перед первым символом в строке, если первый символ является символом слова.
- После последнего символа в строке, если последний символ является символом слова.
- Между двумя символами в строке, где один является символом слова, а другой не является символом слова.
Нашел здесь .Итак, первый символ вашей search_string
- это /
, и кажется, что sed
не может найти границу слова из-за первого правила (потому что /
не является словесным символом).
input_string
, вам нужно сначала выполнить две команды ( echo
и sed
), а затем сохранить результат в переменная input_string
. Для этого поместите две команды внутри $ ()
. Это заставит их выполнить и вернуть результат в вашу переменную (см. Команду в кратком ответе ).
Я знаю, что это неполный ответ, но это все, что у меня есть.
Точное соответствие слов в sed
- сложная задача, особенно если вы хотите написать переносимое решение или если ваше определение слова содержит специальные символы, отличные от _
(как в вашей ситуации).Лучший способ, который я нашел для этого, - рассмотреть все 4 случая, когда слово может появиться в строке ввода:
Если ваше определение слова представляет собой просто последовательность непробельных символов, то следующее решение должно сработать для вас (проверено):
_s = '[] '# содержит пробел и буквальный символ табуляции (CTRL-V + TAB)
input_string = `echo" $ input_string "| sed \
- e "s | ^ $ search_string \\ ($ _ s \\) | \\ 1 | g" \
- e "s | \\ ($ _ s \\) $ search_string $ | \\ 1 | g "\
- e" s | ^ $ search_string $ || g "\
- e" s | \\ ($ _ s \\) $ search_string \ \ ($ _ s \\) | \\ 1 \\ 2 | g "`
Обратите внимание, что я выбрал |
в качестве разделителя вместо #
. Это связано с тем, что #
может отображаться в именах файлов (например, файлы автосохранения Emacs ), а |
зарезервированы, по крайней мере, в Linux. Также обратите внимание, что вывод будет содержать пробельные символы, окружающие каждый экземпляр $ search_string
.Если вы предпочитаете опустить пробел, вы можете использовать его вместо этого (проверено):
_s = '[]' # содержит пробел и буквальный символ табуляции (CTRL-V + TAB)
input_string = ` echo "$ input_string" | sed \
- e "s | ^ $ _ s * $ search_string $ _s \\ {1, \\} || g" \
- e "s | $ _s \\ {1, \\} $ search_string $ _s * $ || g "\
- e" s | ^ $ search_string $ || g "\
- e" s | \\ ($ _ s \\ ) $ search_string $ _s \\ {1, \\} | \\ 1 | g "`
Последнее выражение выглядит немного иначе, и не зря - вы не хотите удалять пробелы с обеих сторон $ search_string
, как только вы зашли так далеко в обработке строки ввода, потому что при этом вы удалили бы пробелы между несогласованными словами по обе стороны от $ search_string
, который бы смешал их вместе.
Заключительные примечания:
g
в
выражениях sed
, но это не так. больно оставлять их внутри. $ search_string
- это путь,
он не может содержать пробелов.