Бих искал да разделя думите, които използват тире sed
, Линиите, които не са вътре в думите, трябва да останат такива. Например за изречението:
"the multi-modal solution is an award-winning approach in the 21st-century - however"
Бих искал изхода:
"the multi @-@ modal solution is an award @-@ winning approach in the 21st @-@ century - however"
Опитах да използвам:
sed "s/([a-zA-Z0-9]+)-([a-zA-Z0-9]+)/1 @-@ 2/g" test.txt > test2.txt
Без успех. Използвам версията OSX на sed.
Отговори:
2 за отговор № 1Можете да използвате тази реализация без regex, като използвате awk
:
s="the multi-modal solution is an award-winning approach in the 21st-century"
awk -F "-" -v OFS=" @-@ " "{$1=$1} 1" <<< "$s"
the multi @-@ modal solution is an award @-@ winning approach in the 21st @-@ century
справка: Ефективно програмиране на AWK
Sed
решение (работи в OSX):
sed -E "s/([^-[:blank:]]+)-([^-[:blank:]]+)/1 @-@ 2/g" <<< "$s"
2 за отговор № 2
За да допълни sed -E
разтвор в отговорът на анубхава с фиксирана версия на вашия собствен опит за решение:
sed "s/([a-zA-Z0-9]{1,})-([a-zA-Z0-9]{1,})/1 @-@ 2/g" test.txt > test2.txt
Това е ERE (ERE)продължен регулярен) количествено конструкт +
трябва да се емулира {1,}
в BRE (основен регулярен), който sed
използва по подразбиране.
Незадължителна основна информация
Като Sundeep изтъква в коментар по въпроса, GNU sed
позволява използването на +
(когато не се използва -r
/ -E
, която позволява поддръжка за EREs), но това е нестандартно разширение, което не се поддържа от macOS sed
версия.
Най- sed
POSIX спец само подпори Bres, специално, POSIX BREs.
Ето защо, да пиша портативен sed
команди:
Не използвайте нито едно от двете
-r
(GNUsed
по-нови версии на BSDsed
) нито-E
(както GNU, така и BSD / macOSsed
)Използвай само POSIX BRE характеристики, като се избягват конкретни разширения, особено:
- употреба
{1,}
вместо+
(еквивалент на ERE+
). - употреба
{0,1}
вместо?
(еквивалент на ERE?
). - Избягвайте GNU
|
за редуване: за съжаление, POSIX BREs не подкрепят промяната.
- употреба
За да се възползвате от по-мощните, модерни-синтаксични EREs, докато поддържате платформи с двете GNU и BSD sed
(включително macOS):
- употреба
-E
за да разрешите ERE. - Използвай само POSIX Функции на ERE.
За да научите за дадено sed
специфични (нестандартни) функции на реализацията на изпълнението:
GNU Sed (Linux):
info sed
, както е от GNU Sed 4.2.2, обясняваGNU BRE синтаксис в глава "3.3 Преглед на синтаксиса на регулярните изрази"
- BRE разширения са
+
,?
, и|
; чеa**
се третира същото катоa*
(без да се налага да избягвате втория*
) е вярно само за Eres.
- BRE разширения са
GNU ERE синтаксис в "Приложение A Разширени регулярни изрази".
- Обсъжда се обаче само контрастът с BREs и многото разширения на ERE - сред тях клавишните символи, като например
d
иs
, твърдения за граница на думи като<
/>
иb
Освен това, последователностите за бягство на контролните знациn
, катоt
и изходни последователности, базирани на кодx27
- са не там.
- Обсъжда се обаче само контрастът с BREs и многото разширения на ERE - сред тях клавишните символи, като например
(Обратно,
man re_format
/man 7 regex
съдържат само информация за POSIX.)
BSD / macOS Сед:
man re_format
се прилага (обсъжда BREs и EREs), с изключение на раздела за подобрено функции, които не се поддържат.- Единствените споменати разширения са твърдения за граница на думи
[[:<:]]
и[[:>:]]
За подробен преглед на всичко разлики между GNU Sed и BSD Sed, виж този отговор от моите.
1 за отговор № 3
Това може да работи за вас (GNU sed):
sed "s/>-</ @-@ /g" file
Заменете хипените, заобиколени от край / начало на граници на думи с необходимия низ.
0 за отговор № 4
s="the multi-modal solution is an award-winning approach in the 21st-century - however"
awk -F century "{gsub(/-/," @&@ ",$1)}1" <<< "$s" OFS=century
the multi @-@ modal solution is an award @-@ winning approach in the 21st @-@ century - however