Search code examples
sedredhat

How to avoid adding word before matched line when word already exists


I created the following sed in order to add the python command exit() before the line LIST_ALL_SELECT_TOOL_PACKAGES_CMD in the file yumrpm.py

 sed -i  '0,/LIST_ALL_SELECT_TOOL_PACKAGES_CMD/s//exit()\n&/' yumrpm.py

Example (after we run the above sed syntax)

exit()
LIST_ALL_SELECT_TOOL_PACKAGES_CMD = "yum list all" 

The problem is when we run the sed again and in this case we get an additional exit().

Example:

exit()
exit()
LIST_ALL_SELECT_TOOL_PACKAGES_CMD = "yum list all" 

What do I need to add in the sed command in order to avoid adding exit() when exit() already exists before the line LIST_ALL_SELECT_TOOL_PACKAGES_CMD?

NOTE - the solution should be inside sed , we dont want to add grep before sed in order to verify if exit() exists


Solution

  • For this task, an awk suits more than sed. Consider this awk solution:

    cat file
    
    exit()
    some line
    LIST_ALL_SELECT_TOOL_PACKAGES_CMD = "yum list 1"
    exit()
    LIST_ALL_SELECT_TOOL_PACKAGES_CMD = "yum list 2"
    LIST_FEW_SELECT_TOOL_PACKAGES_CMD = "yum list 3"
    exit()
    
    awk '!ext && /LIST_ALL_SELECT_TOOL_PACKAGES_CMD/ {print "exit()"}
    {ext = /^exit\(\)/} 1' file
    
    exit()
    some line
    exit()
    LIST_ALL_SELECT_TOOL_PACKAGES_CMD = "yum list 1"
    exit()
    LIST_ALL_SELECT_TOOL_PACKAGES_CMD = "yum list 2"
    LIST_FEW_SELECT_TOOL_PACKAGES_CMD = "yum list 3"
    exit()
    

    This awk commands searches for a line starting with ^exit() and if it finds then sets a flag ext to 1 otherwise sets it to 0.

    Then it prints exit() before a line ONLY if ext is not set to 1 it matches a line starting with LIST_ALL_SELECT_TOOL_PACKAGES_CMD.