I got a html file which is as follows(delete some unuseful words).
<li class="toctree-l1">examples</a></li> <li class="toctree-l3">charcnn</a></li> <li class="toctree-l4">cifar10</a></li>
What I want is to edit it without going into the file (sed command for example). I had a dict which is
dict = {'example':l1, 'charcnn':l2, 'cifar10':l3}
Following the dict, the html file should be
<li class="toctree-l1">examples</a></li> <li class="toctree-l2">charcnn</a></li> <li class="toctree-l3">cifar10</a></li>
Before the replacement it is l1, l3 and l4. After it is l1, l2 and l3.
I know the sed command can replace by key words, but it is used to replace the current words. Is there a way to replace another word on condition of a word in the same row?
Advertisement
Answer
Of course sed can replace one part of a string depending on a different part of the string.
For your example data you could use
sed 's#(<li class="toctree-)[^"]*(">examples</a></li>)#1l12#
s#(<li class="toctree-)[^"]*(">charcnn</a></li>)#1l22#
s#(<li class="toctree-)[^"]*(">cifar10</a></li>)#1l32#' inputfile
The commands check the whole input string but allows anything between toctree- and ".
With this (modified) input
<li class="toctree-l1">examples</a></li> <li class="toctree-l3">charcnn</a></li> <li class="toctree-l4">cifar10</a></li> <li class="toctree-something">other</a></li> <li class="toctree-foo">examples</a></li> <li class="toctree-bar">charcnn</a></li> <li class="toctree-baz">cifar10</a></li>
the output is
<li class="toctree-l1">examples</a></li> <li class="toctree-l2">charcnn</a></li> <li class="toctree-l3">cifar10</a></li> <li class="toctree-something">other</a></li> <li class="toctree-l1">examples</a></li> <li class="toctree-l2">charcnn</a></li> <li class="toctree-l3">cifar10</a></li>
If you have the parameters for the replacement in a dictionary (dict), you could write some code that generates the sed commands from your dictionary in the form
s#(<li class="toctree-)[^"]*("> key </a></li>)#1 value 2#
Depending on your needs you can use different or shorter patterns like
s#("toctree-)[^"]*(">examples<)#1l12#
Edit after clarification of the question in a comment:
To modify the original file you can either save the sed output in a new file and on success rename it to the original file name, e.g.
sed -e 'sed-command' inputfile > outputfile && mv outputfile inputfile
or use the -i option (in-place editing) if available
sed -i -e 'sed-command' inputfile
(Note that you may lose the original input in case your command contains an error.)