Skip to content
Advertisement

Change another word on condition of a word in the same row in command line?

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.)

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement