Search code examples
linuxstringbashawksed

Shell script - remove enclosing quotes(both single and double) from a value in a key/value pair


I have a file file.txt as below, which contains key value pairs separated by a colon-space(: ).

key1: "Subject %D: %W warning(s), %V Violation(s)"
key2: 'sample: value'
key3: "value3"
key4: 'value4'

I want the output as below. Basically remove any single quote or double quote from value and replace colon-space with =.

key1=Subject %D: %W warning(s), %V Violation(s)
key2=sample: value
key3=value3
key4=value4

I have tried awk

awk -F': ' '{ gsub(/^'\''|'\''$/, "", $2); gsub(/^'\"'|'\"'$/, "", $2); print }'  OFS='='

but I am getting the output as below. It is failing when there is a colon-space in the value.

key1=Subject %D=%W warning(s), %V Violation(s)"
key2=sample=value'
key3=value3
key4=value4

Also tried the below sed which having the same problem as awk.

sed -i -e "s/: '/=/" -e "s/'$//" -e 's/: "/=/' -e 's/"$//' -e "s/: /=/" file.txt
key1=Subject %D=%W warning(s), %V Violation(s)
key2=sample=value
key3=value3
key4=value4

Is there is a way I can do this with few lines of code in unix?


Solution

  • You may use this sed solution:

    sed -E "s/: [\"'](.*)[\"']$/=\1/" file
    
    key1=Subject %D: %W warning(s), %V Violation(s)
    key2=sample: value
    key3=value3
    key4=value4
    

    Regex pattern : [\"'](.*)[\"']$ matches colon then a space followed by " or '. Then we match and capture everything in group #1 until we match ending " or '. In the replacement we put = followed by the back-reference of group #1 back.


    If you are looking for an awk solution then use:

    awk -F ": [\"']|[\"']$" -v OFS='=' '{print $1, $2}' file
    
    key1=Subject %D: %W warning(s), %V Violation(s)
    key2=sample: value
    key3=value3
    key4=value4
    

    This awk uses input field separator as colon then a space followed by " or ' OR else " or ' before the end. We use = as output field separator to put = between $1 and $2.