2

I have some string this format:

"User-Password":"aaaa","Calling-Station-Id":"bbbb","Eltex-AVPair":"cccc","h323-call-type":"dddd","Framed-IP-Address":"eeee","NAS-IP-Address":"ffff","Cisco-AVPair":["xpgk-request-type=gggg","xpgk-src-number-in=hhhh","xpgk-dst-number-in=iiii","xpgk-src-number-out=jjjj","xpgk-dst-number-out=kkkk","h323-gw-address=llll"],"Acct-Session-Id":"mmmm","User-Name":"nnnn","Called-Station-Id":"oooo","h323-gw-id":"pppp","Event-Timestamp":"qqqq","h323-conf-id":"rrrr","h323-call-origin":"ssss","NAS-Port-Type":"tttt","NAS-Port":"uuuu"

I need to transform it into

User-Password = "aaaa"
Calling-Station-Id = "bbbb"
Eltex-AVPair = "cccc"
h323-call-type = "dddd"
Framed-IP-Address = "eeee"
NAS-IP-Address = "ffff"
Cisco-AVPair = "xpgk-request-type=gggg"
Cisco-AVPair = "xpgk-src-number-in=hhhh"
Cisco-AVPair = "xpgk-dst-number-in=iiii"
Cisco-AVPair = "xpgk-src-number-out=jjjj"
Cisco-AVPair = "xpgk-dst-number-out=kkkk"
Cisco-AVPair = "h323-gw-address=llll"
Acct-Session-Id = "mmmm"
User-Name = "nnnn"
Called-Station-Id = "oooo"
h323-gw-id = "pppp"
Event-Timestamp = "qqqq"
h323-conf-id = "rrrr"
h323-call-origin = "ssss"
NAS-Port-Type = "tttt"
NAS-Port = "uuuu"

using vim.

So should be something like

:s/\,/\r/g|:s/^\"//g|(something_for_copying_Cisco-AVPair)|:s/\"\:/\ \=\ /g 

It's four parts:

  1. transform , into \r
  2. delete ^"
  3. copying Cisco-AVPair and delete square brackets
  4. transform '":' into ' = '

I can make only write first and last part of these substitutions. How can I deal with others?

6
  • Is there a reason that you need to do this with vim? sed is a better tool. Mar 9, 2021 at 15:14
  • I copy this string from logs to new vim flie, then transform it, then use this file to make some radius-requests. If there is a way to solve my case with sed, it will be helpful. Mar 9, 2021 at 15:47
  • Does that same string appear only once in the file or multiple times? Is its pattern unique? Mar 9, 2021 at 17:15
  • Well, values in "" in output file can be the same in the some cases. But left side of output file (left from =) will be unique Mar 9, 2021 at 17:42
  • Are you sure it's not JSON? In which case use jq Mar 9, 2021 at 20:05

3 Answers 3

2

You could do a series of search/replaces.

:%s/,/\r/g
:%s/^"
:v/:/s/^/Cisco-AVPair":"
:%s/\v":\[?"/ \= "

which translates to

  1. replace each , with a newline
  2. remove all leading quotes
  3. replace start of lines not containing a : with Cisco-AVPair":"
  4. replace all ":[" with = "
2
  • Wow. Works great. I Also added :%s/]// so it deletes also ] symbol. Is there a solution, if there no only Cisco-AVPair, that need to be copied? For example, if string contains "something":[ then copy this "something" Mar 10, 2021 at 16:28
  • You might want to look at this answer I received asking a similar question. It's doable but convoluted. Mar 10, 2021 at 17:47
0

I found next solution for this task:

echo '' | jq -r 'paths(scalars) as $p|[([$p[]|tostring ]|join(".->.") ),(getpath($p)|tojson)]|join(" = ")'|grep '^RAD_REQUEST\.\-'|sed -r 's/^[A-Z_]+\.\->\.//'|sed -r 's/\.\->\.[0-9]+//'

You should enter the request between quotes in order to make it work

1
  • Your command makes assumptions about the input document that is not reflected in the question. For example, what is RAD_REQUEST?
    – Kusalananda
    Oct 15, 2021 at 10:03
0

It looks like you are transforming a JSON document (which you have modified for the sake of the question so that it's no longer a valid JSON document) into TOML. The TOML that you show is not quite valid either as it contains duplicated keys.

Assuming that your original JSON object is

{
  "User-Password": "aaaa",
  "Calling-Station-Id": "bbbb",
  "Eltex-AVPair": "cccc",
  "h323-call-type": "dddd",
  "Framed-IP-Address": "eeee",
  "NAS-IP-Address": "ffff",
  "Cisco-AVPair": [
    "xpgk-request-type=gggg",
    "xpgk-src-number-in=hhhh",
    "xpgk-dst-number-in=iiii",
    "xpgk-src-number-out=jjjj",
    "xpgk-dst-number-out=kkkk",
    "h323-gw-address=llll"
  ],
  "Acct-Session-Id": "mmmm",
  "User-Name": "nnnn",
  "Called-Station-Id": "oooo",
  "h323-gw-id": "pppp",
  "Event-Timestamp": "qqqq",
  "h323-conf-id": "rrrr",
  "h323-call-origin": "ssss",
  "NAS-Port-Type": "tttt",
  "NAS-Port": "uuuu"
}

You may convert this into TOML using a variety of tools, for example yq from https://kislyuk.github.io/yq/ or with yj from https://github.com/sclevine/yj.

With yq,

yq -t . file

or with yj,

yj -jt <file

In both cases, the resulting TOML document would be

User-Password = "aaaa"
Calling-Station-Id = "bbbb"
Eltex-AVPair = "cccc"
h323-call-type = "dddd"
Framed-IP-Address = "eeee"
NAS-IP-Address = "ffff"
Cisco-AVPair = [ "xpgk-request-type=gggg", "xpgk-src-number-in=hhhh", "xpgk-dst-number-in=iiii", "xpgk-src-number-out=jjjj", "xpgk-dst-number-out=kkkk", "h323-gw-address=llll",]
Acct-Session-Id = "mmmm"
User-Name = "nnnn"
Called-Station-Id = "oooo"
h323-gw-id = "pppp"
Event-Timestamp = "qqqq"
h323-conf-id = "rrrr"
h323-call-origin = "ssss"
NAS-Port-Type = "tttt"
NAS-Port = "uuuu"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .