I'm attempting to parse email body to excel file.
After some manipulations, my current output is an array, where each line is data related to a product.
[Β Β
"Periods: 01.01.2023 - 01.02.2023 | Code: 111 | Code2: 1111 | product-name",Β Β
"Periods: 01.01.2023 - 01.02.2023 | Code: 222 | Code2: 2222 | product-name2"
]
I need to replace the 3rd occurrence of " | " with " | Product: " , so i can get field Product before the product name.
I've tried to use Apply to each -> current item -> various ways to find 3rd occurrence and replace it, but can't succeed.
Any suggestion?
You should be able to loop through each item and perform a simple replace expression like thus ...
replace(item(), split(item(), ' | ')[3], concat('Product: ', split(item(), ' | ')[3]))
That should get you across the line. Of course, I'm basing my answer off the limited information you provided.
Related
What is the best way to do this and how?
I gather things called sed, AWK and bash may be relevant.
I have used AWK once for one command, the others never.
I have searched and other apparently similar questions do not have an answer I need.
I have columns I have called fields in a CSV file:
_________________________
field1 | field2 | field3|
-------------------------
1990AB | 123456 | 123456|
-------------------------
I want to add fields based on these three original fields to appear as follows:
_______________________________________________________
field1 | field2 | field3 | field1a | field2a | field3a |
-------------------------------------------------------
1990AB | 123456 | 123456| 1990 | 12345 | 12345 |
-------------------------------------------------------
where:
field1a 1990 column 1 first 4 always digits then alpha
field2a 12345 column 2 is always 6 digits
field3a 12345 column 3 is always 6 digits
These are one-time-per-file actions, prior to database import.
macosx has about 6 million records. 2nd attempt at this question as my first was apparently not good. In this area I am a 100% novice.
awk to the rescue!
this should be easy to read even if you have no prior experience with awk
$ awk -F, -v OFS=, 'NR==1 {for(i=1;i<=3;i++) $(++NF)=$i"a"}
NR>1 {$(++NF)=substr($1,1,4);
$(++NF)=substr($2,1,5);
$(++NF)=substr($3,1,5)}1' file
NR is line number, special treatment for header, NF is number of fields, here incrementing for each additional column and $i is field value at position i. The last 1 is shorthand for printing the line. Initial options are for setting input field delimiter (F) and output field delimiter (OFS) to comma.
I have put the data from a file into an array, then I am just staying with the data I want of that array which looks like follows:
Basically what I want, is to access each column independently. As the file will keep changing I don't want something hard coded, I would have done it already :).
Element0: | data | address | type | source | disable |
Element1: | 0x000001 | 0x123456 | in | D | yes |
Element2: | 0x0d0f00 | 0xffffff | out | M | yes |
Element3: | 0xe00ab4 | 0xaefbd1 | in | E | no |
I have tried with the regexp /\|\s+.*\s+\|/it prints just few lines (it removes the data I care of). I also tried with /\|.*\|/ and it prints all empty.
I have googled the split method and I know that this is happening it is because of the .* removing the data I care of. I have also tried with the regexp \|\s*\| but it prints the whole line. I have tried with many regexp's but at this moment I can't think of a way to solve this.
Any recommendation?
`line_ary = ary_element.split(/\|\s.*\|/)
unless line_ary.nil? puts line_ary`
You should use the csv class instead of trying to regex parse it. Something like this will do:
require 'csv'
data = CSV.read('data.csv', 'r', col_sep: '|')
You can access rows and columns as a 2 dimentional array, e.g. to access row 2, column 4: data[1][3].
If for example you just wanted to print the address column for all rows you could do this instead:
CSV.foreach('data.csv', col_sep: '|') do |row|
puts row[2]
end
I'd probably use a CSV parser for this but if you want to use a regex and you're sure that you'll never have | inside one of the column values, then you want to say:
row = line.split(/\s*\|\s*/)
so that the whitespace on either side of the pipe becomes part of the delimiter. For example:
> 'Element0: | data | address | type | source | disable |'.split(/\s*\|\s*/)
=> ["Element0:", "data", "address", "type", "source", "disable"]
> 'Element1: | 0x000001 | 0x123456 | in | D | yes |'.split(/\s*\|\s*/)
=> ["Element1:", "0x000001", "0x123456", "in", "D", "yes"]
Split together with strip might be the easiest option. Have you tried something like this?
"Element3:...".split(/\|/).collect(&:strip)
I'm currently trying to test a service that should be properly replacing certain special characters within a certain Unicode range, including emojis, transportation icons, emoticons and dingbats. I have been using Cucumber and Ruby to do the testing, and my latest scenario outline won't work. I've tried looking up other ways of getting the character from the examples table, however I can't seem to get it working, and the cucumber printout just complains that the Given step isn't defined.
Here is my feature scenario:
Scenario Outline: I update a coupon with a name including emojis/emoticons/dingbats/symbols
Given I have a name variable with a <character> included
When I patch my coupon with this variable
Then the patch should succeed
And the name should include replacement characters
Examples:
| character |
| π³ |
| π
|
| π₯ |
| π |
| β |
| β |
| β |
| β |
| β¨ |
| π |
| π¦Ώ° |
And Here is my step definition for the Given (which is the step that is complaining that it isn't defined)
Given(/^I have a name variable with a (\w+) included$/) do |char|
#name = 'min length ' + char
#json = { 'name' => #name }.to_json
end
I've tried using some regex's to capture the character, and a (\w+) and (\d+), although I can't find information on how to capture the special character. It's possible for me to write 11 different step definitions, but that would be such poor practice it would drive me nuts.
Unless you have spaces in your specials, itβs safe to use non-space \S:
Given(/^I have a name variable with a (\S+) included$/) do |char|
...
\w would not give you the desired result, since \w is resolved to [a-zA-Z0-9_].
Is there any way to add a description to possible values of URI parameter?
## Search Items [/items{?s}]
### Get items [GET]
+ Parameters
+ s (optional, values) ... Sort results by
+ Values
+ `1 - price`
+ `4 - date`
If I use the approach given above, then I can not define example and default values (for ex., 4), since it expects the full value (4 - date).
No, there is currently no way to add description to possible values of URI parameters.
Neither
+ Values
+ `A - means something`
+ `B`
+ `C`
or
+ Values
+ `A` means something
+ `B`
+ `C`
will work correctly. I filed a feature request under API Blueprint's repository. If you want to be part of the design process and help us to get the best solution to your problem, you can track it and comment under it.
Using tables
When in troubles with API Blueprint, you can always use plain old Markdown in endpoint's description to supplement or substitute what's missing. E.g. you can freely use tables as an addition or replacement to the Values section:
# My API
## Sample [/endpoint{?id}]
Description.
| Value | Meaning |
| ------------ |:----------------:|
| A | Alaska |
| B | Bali |
| C | Czech Republic |
+ Parameters
+ id (string)
Description...
| Value | Meaning |
| ------------ |:----------------:|
| A | Alaska |
| B | Bali |
| C | Czech Republic |
Description...
+ Values
+ `A`
+ `B`
+ `C`
I am using a scenario table (multiline step arguments) to check some data from a screen using cucumber, using the in built .diff! method on the Cucumber AST table.
I would like to check the content matches against regular expressions.
Scenario: One
Then the table appears as:
| One | Two | Three |
| /\d+/ | /\d+/ | /\d+/ |
The actual table could look something like
| One | Two | Three |
| 123 | 456 | 789 |
which this scenario is translated to "as long as there are some digits, I don't care"
An example step implementation that fails:
Then /^the table appears as:$/ do |expected_table|
actual_table = [['One','Two', 'Three'],['123', '456', '789']]
expected_table.diff! actual_table
end
Error:
Then the table appears as: # features/step_definitions/my_steps.rb:230
| One | Two | Three |
| /\\d+/ | /\\d+/ | /\\d+/ |
| 123 | 456 | 789 |
Tables were not identical (Cucumber::Ast::Table::Different)
I have tried using step transforms to transform the cells into regular expressions, but they still aren't identical.
Transform code:
expected_table.raw[0].each do |column|
expected_table.map_column! column do |cell|
if cell.respond_to? :start_with?
if cell.start_with? "/"
cell.to_regexp
else
cell
end
else
cell
end
end
end
which provides the eror:
Then the table appears as: # features/step_definitions/my_steps.rb:228
| One | Two | Three |
| (?-mix:\\d+) | (?-mix:\\d+) | (?-mix:\\d+) |
| 123 | 456 | 789 |
Tables were not identical (Cucumber::Ast::Table::Different)
Any ideas? I am stuck.
Using regular expressions in a scenario is almost certainly the wrong approach. Cucumber features are intended to be read and understood by business-focussed stakeholders.
How about writing the step at a higher level, such as as:
Then the first three columns of the table should contain a digit
There is no way to do it without writing your own implementation of diff! method from Ast::Table. Take a look into cucumber/lib/ast/table.rb. Internally it uses diff-lcs library to do an actual comparison which doesn't support regex match.
It seems that you want to write this in a way that provides the cool diff output. Otherwise, I'd look at writing this such that you simply check the rows. It won't be as pretty, and it won't get you the diff of the entire table, but it's something.
Then /^the table appears as:$/ do |expected_table|
actual_table = [['One','Two', 'Three'],['123', '456', '789']]
expected_table.raw.each_with_index { |row, y|
row.each_with_index { |cell, x|
actual_table[x][y].should == cell
}
}
end