Search code examples
ubuntused

Sed command ubuntu terminal


I'm trying to figure out how to do this on Ubuntu Terminal console.

I have this file /home/users/user/config.cfg and I need every 24 hours replace 1 specific text that repeats many times on each config block. I setup a cronjob that runs every 24 hours but I can't figure out the sed command to get this.

Example:

{"Name": "John Snow","Email": "[email protected]","Data": [{"User-Data": "data-0001","Login-Data": "data-20240601180000","Cred-Data": "data-CR0909123"},{"User-Data": "data-0002222","Login-Data": "data-20240601180000","Cred-Data": "data-CR090911212123"},{"User-Data": "data-000112121212121","Login-Data": "data-20240601180000","Cred-Data": "data-CR090912123"}]}

I need to replace all lines were "User-Data": string appears to this:

"User-Data": "Clear",

I can't use Data* because the word Data- appears on otter json items, for example "Login-Data": "Data-20240601180000" so the mandatory key is "User-Data": starting line.

Any idea how to do that with sed or another way.


Solution

  • Since it is JSON, you can use jq:

    cfg=/home/users/user/config.cfg
    jq '.Data[]."User-Data" = "Clear"' "$cfg" | sponge "$cfg"
    

    (sponge comes from the moreutils package. Or see: jq to replace text directly on file (like sed -i))

    jq will by default pretty-print its output:

    {
      "Name": "John Snow",
      "Email": "[email protected]",
      "Data": [
        {
          "User-Data": "Clear",
          "Login-Data": "data-20240601180000",
          "Cred-Data": "data-CR0909123"
        },
        {
          "User-Data": "Clear",
          "Login-Data": "data-20240601180000",
          "Cred-Data": "data-CR090911212123"
        },
        {
          "User-Data": "Clear",
          "Login-Data": "data-20240601180000",
          "Cred-Data": "data-CR090912123"
        }
      ]
    }
    

    Adding -c option will make output more compact:

    {"Name":"John Snow","Email":"[email protected]","Data":[{"User-Data":"Clear","Login-Data":"data-20240601180000","Cred-Data":"data-CR0909123"},{"User-Data":"Clear","Login-Data":"data-20240601180000","Cred-Data":"data-CR090911212123"},{"User-Data":"Clear","Login-Data":"data-20240601180000","Cred-Data":"data-CR090912123"}]}
    

    If you must use sed, you could try with GNU sed:

    sed -Ei 's/("User-Data"\s*:\s*")(\\"|[^"])*/\1Clear/g' "$cfg"
    

    {"Name": "John Snow","Email": "[email protected]","Data": [{"User-Data": "Clear","Login-Data": "data-20240601180000","Cred-Data": "data-CR0909123"},{"User-Data": "Clear","Login-Data": "data-20240601180000","Cred-Data": "data-CR090911212123"},{"User-Data": "Clear","Login-Data": "data-20240601180000","Cred-Data": "data-CR090912123"}]}
    

    Adding -z option may help if real data is not actually a single line as shown in the example.