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