Jaký je dobrý způsob, jak nahradit řetězec v souboru pomocí slovníku s a lot párů substituent-substituent? A hodně , ve skutečnosti myslím asi 20 – ne moc, ale dost na to, abych je chtěl úhledně uspořádat.
Chci shromáždit všechny páry substituend-substituent do souboru dictionary.txt
snadno ovladatelným způsobem, protože potřebuji vyměnit spoustu věcí, řekněte jako:
"yes" : "no"
"stop" : "go, go, go!"
"wee-ooo" : "ooooh nooo!"
"gooodbye" : "hello"
"high" : "low"
"why?" : "i don't know"
Nyní chci tyto substituce použít v nějakém souboru novel.txt
.
Poté chci spustit magiccommand --magicflags dictionary.txt novel.txt
takže všechny výskyty yes
v novel.txt
jsou nahrazeny no
(takže i Bayesian
bude nahrazeno Banoian
) a všechny výskyty goodbye
v novel.txt
bude nahrazeno hello
a tak dále.
Řetězce, které potřebuji nahradit (a nahradit), zatím ne obsahovat žádné uvozovky (ani jednoduché, ani dvojité). (Bylo by však hezké, kdyby řešení fungovalo dobře s řetězci obsahujícími uvozovky, samozřejmě.)
Znám sed
a awk
/ gawk
umí takové věci principiálně, ale mohou také pracovat s takovými soubory slovníku? Vypadá to jako gawk
by byl správným kandidátem pro magiccommand
, jaké jsou správné magicflags
? Jak musím naformátovat svůj dictionary.txt
?
Přijatá odpověď:
Zde je jeden způsob s sed
:
sed '
s|"(.*)"[[:blank:]]*:[[:blank:]]*"(.*)"|1
2|
h
s|.*n||
s|[&/]|\&|g
x
s|n.*||
s|[[.*^$/]|\&|g
G
s|(.*)n(.*)|s/1/2/g|
' dictionary.txt | sed -f - novel.txt
Jak to funguje:
1. sed
změní dictionary.txt
do souboru skriptu (příkazy pro úpravu, jeden na řádek). Toto je směrováno do 2. sed
(všimněte si -f -
což znamená číst příkazy z stdin
), který tyto příkazy provede, úpravou novel.txt
.
To vyžaduje překlad vašeho formátu
"STRING" : "REPLACEMENT"
do sed
příkaz a escapování všech speciálních znaků v procesu pro oba LHS
a RHS
:
s/ESCAPED_STRING/ESCAPED_REPLACEMENT/g
Takže první střídání
s|"(.*)"[[:blank:]]*:[[:blank:]]*"(.*)"|1
2|
otočí "STRING" : "REPLACEMENT"
do STRINGnREPLACEMENT
(n
je znak nového řádku). Výsledek je poté zkopírován přes h
starý prostor.s|.*n||
odstraní první část a ponechá pouze REPLACEMENT
pak s|[&/]|\&|g
escapuje vyhrazené znaky (toto je RHS
).
To pak ex
změní vyrovnávací paměť s prostorem vzoru a s|n.*||
odstraní druhou část a ponechá pouze STRING
a s|[[.*^$/]|\&|g
provádí escapování (toto je LHS
).
Obsah vyrovnávací paměti je poté připojen k prostoru vzorů pomocí G
takže nyní je obsah vzorového prostoru ESCAPED_STRINGnESCAPED_REPLACEMENT
.
Konečné střídání
s|(.*)n(.*)|s/1/2/g|
převede jej na s/ESCAPED_STRING/ESCAPED_REPLACEMENT/g