Splunk Search

How to easily replace a character in a token value ?

ctaf
Contributor

Hello,

I have a token "user" representing the name of a user. This name can contain "(" or ")". When I am using this token to execute a LDAP search, I get an error because it cannot contains brackets. The solution is to replace

 ( by \28

and

) by \29.

I tried it without using the token, and it works:

 | ldapsearch domain=mydoman search="(CN=John Doe \\28test\\29)"

Unfortunately, I am using a dashboard to automatically complete this username. I need to replace the brackets by \28 and \29.
Is there a quick way to do this?

Thank you

0 Karma
1 Solution

javiergn
Super Champion

This would be my approach (simply replace myToken with $yourtoken$ and it should work):

| eval myToken = "(CN=John Doe (test))"
| rex field=myToken mode=sed "s/(^\(.+)(\()/\\1\\\\\28/g"
| rex field=myToken mode=sed "s/([^\)]+)(\))(.*\)$)/\\1\\\\\29\\3/g"

output: (CN=John Doe \\28test\\29) 

Alternatively, this one is a bit more robust as it should replace ALL your parenthesis and then fix your LDAP string by appending opening and closing ones:

| eval myToken = "(CN=John Doe (test))"
| eval myToken = replace(myToken, "\(", "\\\\\28") 
| eval myToken = replace(myToken, "\)", "\\\\\29")
| rex field=myToken "^\\\\\\\\28(?<tempToken>.+)\\\\\\\\29$"
| eval myToken = "(" . tempToken . ")"
| fields - tempToken

output: (CN=John Doe \\28test\\29) 

Alternative number 3 as suggested below:

| gentimes start=-1
| eval myToken = replace($token$, "\(", "\\\\\28") 
| eval myToken = replace(myToken, "\)", "\\\\\29")
| rex field=myToken "^\\\\\\\\28(?<tempToken>.+)\\\\\\\\29$"
| eval myToken = "(" . tempToken . ")"
| fields - tempToken
| map search="| ldapsearch domain=mydoman search=\"$$myToken$$\""

Let me know if that helps.

Thanks,
Javier

View solution in original post

0 Karma

javiergn
Super Champion

This would be my approach (simply replace myToken with $yourtoken$ and it should work):

| eval myToken = "(CN=John Doe (test))"
| rex field=myToken mode=sed "s/(^\(.+)(\()/\\1\\\\\28/g"
| rex field=myToken mode=sed "s/([^\)]+)(\))(.*\)$)/\\1\\\\\29\\3/g"

output: (CN=John Doe \\28test\\29) 

Alternatively, this one is a bit more robust as it should replace ALL your parenthesis and then fix your LDAP string by appending opening and closing ones:

| eval myToken = "(CN=John Doe (test))"
| eval myToken = replace(myToken, "\(", "\\\\\28") 
| eval myToken = replace(myToken, "\)", "\\\\\29")
| rex field=myToken "^\\\\\\\\28(?<tempToken>.+)\\\\\\\\29$"
| eval myToken = "(" . tempToken . ")"
| fields - tempToken

output: (CN=John Doe \\28test\\29) 

Alternative number 3 as suggested below:

| gentimes start=-1
| eval myToken = replace($token$, "\(", "\\\\\28") 
| eval myToken = replace(myToken, "\)", "\\\\\29")
| rex field=myToken "^\\\\\\\\28(?<tempToken>.+)\\\\\\\\29$"
| eval myToken = "(" . tempToken . ")"
| fields - tempToken
| map search="| ldapsearch domain=mydoman search=\"$$myToken$$\""

Let me know if that helps.

Thanks,
Javier

0 Karma

ctaf
Contributor

The problem is that this solution uses the token value in the "field=XXX" option.

| rex field=John Doe (test) mode=sed "s/(^(.+)(()/\1\\\28/g"
| rex field=John Doe (test) mode=sed "s/([^)]+)())(.*)$)/\1\\\29\3/g"

0 Karma

javiergn
Super Champion

I see what you mean. Sorry i don't have an easy way to test this but what about the following using the map command?

| gentimes start=-1
| eval myToken = replace($token$, "\(", "\\\\\28") 
| eval myToken = replace(myToken, "\)", "\\\\\29")
| rex field=myToken "^\\\\\\\\28(?<tempToken>.+)\\\\\\\\29$"
| eval myToken = "(" . tempToken . ")"
| fields - tempToken
| map search="| ldapsearch domain=mydoman search=\"$$myToken$$\""

EDIT: fixed query above as there was a typo because of the copy and paste
EDIT2: adding double $ to myToken

0 Karma

ctaf
Contributor

This solution give me a "The search is waiting for input" message on my dashboard. I guess it is because "$myToken$" is not set.

EDIT: I think I missed your "edit". What did you change?

0 Karma

somesoni2
Revered Legend

Use double $ sign for mytoken.

0 Karma

ctaf
Contributor

That's what I did: | ldapsearch domain=mydomain search=\"(CN=$myToken$)\"

0 Karma

somesoni2
Revered Legend

No like this

 | ldapsearch domain=mydomain search="(CN=$$myToken$$)"
0 Karma

ctaf
Contributor

Oh OK. We're progressing, but it still doesn't work. I am not sure what is "tempToken" for as it is empty and the last "eval myToken" makes "myToken" empty too... Very strange.

0 Karma

javiergn
Super Champion

That was just me wanting to display all the different field values for debugging purposes in my test query. Feel free to get rid of it:

| gentimes start=-1
| eval myToken = replace($token$, "\(", "\\\\\28") 
| eval myToken = replace(myToken, "\)", "\\\\\29")
| rex field=myToken "^\\\\\\\\28(?<myToken>.+)\\\\\\\\29$"
| eval myToken = "(" . myToken . ")"
| map search="| ldapsearch domain=mydoman search=\"$$myToken$$\""
0 Karma

ctaf
Contributor

Yeah ! I managed to make it work:

| gentimes start=-1 | eval myToken = replace("$user$", "\(", "\\28")   | eval myToken = replace(myToken, "\)", "\\29")  | map search="| ldapsearch domain=mydomain search=\"(CN=$$myToken$$)\""

Splunk was showing only 2 backslash in when you set up 5 of them but when using it in the LDAP search, it needed only 2...

I removed the rex function and the last eval too.

I have one more question: What is "gentimes" for ?

0 Karma

javiergn
Super Champion

That's just for my example to be able to use non search commands when you don't really have a search. You can use "| stats count" too.

It is quite useful when testing things as otherwise you need to start your search with an actual search or input type command.

There are other uses for gentimes of course. See the doc

jplumsdaine22
Influencer

Use eval replace() to reformat the token value

| eval foo=replace($token$),"\(","\28") |eval foo=replace(foo,"\)","\29") |  ldapsearch domain=mydomain search=foo

See replace() in http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Commonevalfunctions

0 Karma

ctaf
Contributor

This is something I tried but if I do that, "foo" won't be evaluated. So the LDAP Search string is just the string "foo".

0 Karma

jplumsdaine22
Influencer

Use map as well then:

| eval foo=replace($token$),"\(","\28") |eval foo=replace(foo,"\)","\29") | map search="| ldapsearch domain=mydoman search=$foo$"
0 Karma

ctaf
Contributor

Thank you !

0 Karma
Get Updates on the Splunk Community!

Announcing Scheduled Export GA for Dashboard Studio

We're excited to announce the general availability of Scheduled Export for Dashboard Studio. Starting in ...

Extending Observability Content to Splunk Cloud

Watch Now!   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to leverage ...

More Control Over Your Monitoring Costs with Archived Metrics GA in US-AWS!

What if there was a way you could keep all the metrics data you need while saving on storage costs?This is now ...