Pomocí sed
, jak by se vkládal text za znak, který předchází (nebo následuje) nějaký řetězec pomocí N
výskytů. Předpokládejme například, že řádek textu, který se má upravit, je následující:
command -some -args -c 'a quoted section;some;lines;of code;keyword;more lines;etc();'
Po nalezení tohoto řádku v textovém souboru (možná prostřednictvím jedinečného řetězce command
), chci vložit text za druhý (N=2) středník před keyword
(tj. středník oddělující lines
a of
). Konkrétně bych chtěl použít sed
za tímto účelem.
Pokračujeme-li v tomto příkladu, očekávaný výstup by byl:
command -some -args -c 'a quoted section;some;lines;INSERTED_STRING;of code;keyword;more lines;etc();'
kde INSERTED_STRING;
(poskytovaný do sed, např. prostřednictvím proměnné shellu) byl vložen na požadovanou pozici.
Přijatá odpověď:
Upřednostňuji to jednoduché:
sed '/command/s/[^;]*;keyword/INSERTED_STRING;&/'
pro vložení dvou polí před klíčové slovo. Obecné řešení by bylo
sed "/command/s/\([^;]*;\)\{$N\}keyword/INSERTED_STRING;&/"
ale všimněte si, že N
má offnet 1 ve srovnání s vaší otázkou:Zde N=2
znamená mít dvě pole mezi vložkou a keyword
.
Vysvětlení:/command/
vybere pouze řádky s command
, takže ostatní řádky zůstanou nedotčeny. ([^;]*;\)
odpovídá jednomu poli (posloupnosti jiných než středníků) včetně následujícího středníku. Pokud jej budete následovat pomocí \{$N\}
vzor odpovídá $N
pole. Následující keyword
dokončí to, aby odpovídalo keyword
a $N
pole dříve. Vzor náhrady se skládá z vloženého řetězce a &
, který je nahrazen vším, co bylo spárováno (takže to nakonec nebyla náhrada, ale vložka).
Zkrácené a lépe čitelné s rozšířenými regulárními výrazy:
sed -E "/command/s/([^;]*;){$N}keyword/INSERTED_STRING;&/"