jq replace substring in value - bash

This the output of my curl
{
"expand": "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id": "240937",
"self": "https://placeholder.atlassian.net/rest/api/latest/issue/240937",
"key": "placeholder-355",
"fields": {
"description": "We need the following page layout changes made (for all user profiles unless specified in front of the item):\n\n# Display {{TestAccount__c}} field on the account object underneath the *Pricing Group* field\n# Display {{blng__LegalEntity__c}} field that sits on {{Order Product}} to be visible on *Order* as well as *Contract* objects _(position doesn’t matter). Read only is fine as long as that works on SF reports if we need to bring this attribute in_\n# Display {{blng__LegalEntity__c}} field that sits on *Invoice Lines* to be visible on the *Invoice* object _(position doesn’t matter). Read only is fine as long as that works on SF reports if we need to bring this attribute in_\n# Display ‘*Notes*’ section on the credit request page - copy the one that exists on the contract object e.g. (sample below)\n!image-20220714-021135.png|width=50%!\n# -Display- *-Agent-* -field on contract object to enable users to see if account has an agent or not- → already in production (not needed)\n# Change default options for *tasks* - the default subjects are:\n#* Call\n#* Send Letter\n#* Send Quote\n#* Other\n# Need to update to the following:\n#* Call\n#* Video Call\n#* Face to Face Meeting\n# Add in *Contact hierarchy* functionality in Salesforce\n## Anyone can update the ‘Reports to’ field\n## Show the following fields on the hierarchy page"
}
}
With jq I'm getting json
jq --raw-output '.fields.description' jira-story.json
Result:
# Display *Pricing Group* field
# Display *Contract*
# Change default options for *tasks* - the default subjects are:
#* Call
#* Send Letter
#* Send Quote
#* Other
# Need to update to the following:
#* Call
#* Video Call
#* Face to Face Meeting
# Add in *Contact hierarchy*
## Anyone can update the ‘Reports to’ field
## Show the following fields on the hierarchy page
I want it nicely format it as
### Display *Pricing Group* field
### Display *Contract*
### Change default options for *tasks* - the default subjects are:
- Call
- Send Letter
- Send Quote
- Other
### Need to update to the following:
- Call
- Video Call
- Face to Face Meeting
### Add in *Contact hierarchy*
- Anyone can update the ‘Reports to’ field
- Show the following fields on the hierarchy page
How can I replace the value in a jq before the output?
"#*" to "-" or "##" to "-" and "#" to "###"

You don't necessarily need to perform the substitution in jq, you can pipe the output to sed:
jq -r '.fields.description' | sed 's/^#[#*]/-/;s/^#/###/'
If you really must do it with a single jq expression, then what user jhnc wrote in the comments:
jq -r '.fields.description | gsub("\n#[#*]";"\n-") | gsub("\n# ","\n### ")'

Related

Vector dev how to use hypenated key names?

Sometimes, when processing log events in vector, a log source might have hyphens as key names - for example json structured logs. Assuming it is from a third party and changing them there is not an option, how can we handle these keys?
A sample log message (contrived for demonstration) is:
{
"labels":{"no_hypens":"normal field","this-has-hypens":"this is a test"},
"message":"a message",
"timestamp":"2022-11-01T12:03:00.941866394Z"
}
Note the field labels.this-has-hyphens there.
I managed to put together a test case, and find out the syntax, both in providing test data like this and in extracting the data in VRL:
The test case
---
tests:
- name: hypens
inputs:
- insert_at: hypens
type: log
log_fields:
labels."this-has-hypens": "this is a test"
labels.no_hypens: "normal field"
outputs:
- extract_from: hypens
conditions:
- type: vrl
source: |
assert_eq!("normal field", .no_hypens)
assert_eq!("this is a test", .output_without_hypens)
This will insert and check for two fields from the input data. Note the hyphenated key segment needs to be quoted.
Next the VRL in the transform:
---
transforms:
hypens:
type: remap
inputs:
- route
source: |
log(., "error")
. = {
"no_hypens": .labels.no_hypens,
"output_without_hypens": .labels."this-has-hypens",
}
The log message is there as while debugging this, I had to figure out that the test hyphenated field didn't even get to the transform until I had quotes around it.
Then the field reference itself needs to have quotes too, after the dot (not square brackets).
This will pass the tests, and output the right data.

Xpath for text between tag with space in between after every tag change

text is like
<tag>Head Office41-43 Ricketts Road<tag/> <tag>Mount Waverley, Melbourne<tag/>
iam getting result as
Head Office41-43 Ricketts RoadMount Waverley, Melbourne
but i want it as
Head Office41-43 Ricketts Road Mount Waverley, Melbourne
code i am using is
response.xpath('string(normalize-space(//*/text()[contains(normalize-space(), "{}")]/../..))'.format(marker))
where marker is the text.
so instead of RoadMount I want Road Mount
see the tag wrapped:
enter image description here
this is the code iam using
enter image description here
Your xpath is returning multiple values - all you have to do is join them with a separator:
xpath = 'string(normalize-space(//*/text()[contains(normalize-space(), "{}")]/../..))'.format(marker))
results = " ".join(response.xpath(xpath).getall())
# ^^^^^^^^
# note: don't forget to use getall to retrieve all results
print(results)

Make step definition dynamic to handle any incoming text

I have to run test1.feature file against two urls. In one of the url I have got a field named as EIN, but in second url the same field named as ABN
How can we make the step definition dynamic to handle any text coming in second string.
Url 1 : https://testsite.us.com/student
The Field is named as "EIN"
Url 2: https://testsite.au.com/student
The Field is named as "ABN"
test1.feature
And I type "11 234 234 444" in "ABN" field
step_definition
//Type text value in textbox input field
Then('I type {string} in {string} field', (textval, textboxname) => {
switch (textboxname) {
case "Email":
case "Work Phone":
case "ABN":
case "EIN":
case "ACN":
cy.get('#profile_container').parent().find('.fieldHeaderClass').contains(textboxname)
.next().find('input')
.clear({force:true})
.type(textval, { force: true });
break;
//final else condition
default:
cy.get('#profile_container').parent().find('.fieldHeaderClass').contains(textboxname)
.next()
.type(textval, { force: true });
}
});
First of all a great tip: Make use of page objects (POM design pattern). A page objects is an object (inside a third .js file besides your features and stepdifinitions) that you import in the stepdefinitions file that contains all of your selector code (cy.get(......)). You don't want selector code in your stepdefinitions. Makes it messy and more difficult to read.
Concerning your problem: If you want to repeat the same logic for (all kinds of) input values. Why not write your logic just ones (so without the long case statement) and use Scenario Outline to repeat your step for the different inputs? If your logic must be different every time, than don't even bother fixing this problem. Then you should simply write different steps for different logic..
Here is an example of scenario outline (inside a .feature):
Scenario Outline: Scenario Outline name
Given I type "<textval>" in "<textboxname>" field
Examples:
| textval | textboxname |
| some_value | ABN |
| some_other_value | EIN |
| some_other_value_2 | email |
| some_other_value_3 | ACN |
| some_other_value_4 | Work Phone |
Conclusion: Use Scenario Outline to repeat logic. If logic needs to be different for different inputs, then write another stepdefinition and don't try to combine and clip different logics into 1 step.

How to iterate the split data using robot framework. I have 3 scenarios to validate based on this functionality

Profile User
${profile_user} ${profile_domain}= Split String ${username} separator=#
${profile_user}= Replace String ${profile_user} - ${SPACE}
${profile_user}= Convert To Uppercase ${profile_user}
[Return] ${profile_user}
# Both are equal , but still return None
Validate Owner field
[Arguments] ${owner}
${text}= Convert To Uppercase ${owner}
${profile_user}= Profile User
log ${text}
${status}= should contain ${profile_user} ${text}
[Return] ${status}
# We can validate awp text
Validate softwarebundle field
[Arguments] ${softwarebundle} ${bundle_id}
${bundle_id}= Convert To Uppercase ${bundle_id}
${bundle_id}= Replace String ${bundle_id} - ${SPACE}
${status}= should contain ${softwarebundle} ${bundle_id}
[Return] ${status}
**# I want to validate weather complete date is matching with the same format using current date**
Validate Create time
[Arguments] ${expdate}
${UI_Creation_time}= Set Variable ${text}
${CurrentDate} = Get Current Date result_format=%m/%d/%Y
Log ${CurrentDate}
${status}= should contain ${text} ${CurrentDate}
[Return] ${status}
****Data:
${username}= UAT APP USER
${owner}= UAT APP USER
${softwarebundle}= awp 9.4 se
${bundle_id}= awp
${expdate}= 06/30/2020 6.40PM****
**Using above data , we should get the status as True for every function, then only i can proceed with another functionality.
For 2nd function i am trying to validate complete data using should be equal keyword in framework, But it is returns None
For 3rd function i am using Should contain keyword. For 1st variable we are getting data as 'awp ss wrd' , here i want to validate 'aws' is available or not , still condition fails
For 4th , i want to validate date with the format of '06/30/2020 6.40 PM', Here i tried by validating only date without time, still it returns None.
To get return status of variable true false please try to use this keyword Run Keyword And Return Status
${status}= Run Keyword And Return Status should contain ${profile_user} ${text}
the expected result will be True and False.
Document

Deleting the "\r" or carriage return from a string in Ruby

I am using CloudMailin to receive emails and then send the plain text to my Ruby on Rails app. To access the body of the email in plain text I use params[:plain].
If I were to just print the relevant part of the plain text it would look like this:
Style 130690 113
Price $335.00
Stock # 2882524
I have used regex to name capture certain pieces of data:
style, price, stock = params[:plain].scan(/^(?:Style |Price \$|Stock \# )(.+)/).flatten
This works however each variable has a "\r" or carriage return at the end. So, if stock is 80201943, it would appear in my database as "80201943\r".
I then try to update my database with this code:
shoe = Shoe.where(:size => "7").first
shoe.update_column(:stockId, stock)
Then when I check my database the :stockId has a "\r" at the end of it.
I have tried doing
stock.chomp("\r")
stock.chomp
stock.strip
stock.gsub("\r", ""),
None of these remove the "\r" from the string. How can I remove it?
I was not altering the variable, I was just returning a new one. To alter the variable I needed to use:
stock.chomp!

Resources