assign array value to ENV var on .env file - ruby-on-rails

I need to set an array of strings on my .env file and cant find information about the right syntax. Test for this takes quite a while so I wanted to save some time. Some of this options should work:
MY_ARRAY=[first_string, second_string]
MY_ARRAY=[first_string second_string]
MY_ARRAY=['first_string', 'second_string']
Can someone tell me which?

As far as I know dotenv does not allow setting anything except strings (and multiline strings). The parser syntax is:
LINE = /
\A
(?:export\s+)? # optional export
([\w\.]+) # key
(?:\s*=\s*|:\s+?) # separator
( # optional value begin
'(?:\'|[^'])*' # single quoted value
| # or
"(?:\"|[^"])*" # double quoted value
| # or
[^#\n]+ # unquoted value
)? # value end
(?:\s*\#.*)? # optional comment
\z
/x
The reason behind this is shell and OS support for setting other types of env variables is spotty.
You could use a separator such as commas or pipes (|) and split the string with ENV['FOO'].split('|'). But maybe what you are trying to do should be solved with an initializer which combines ENV vars.

Related

GNU make .env:6: *** unterminated variable reference. Stop

I have windows 10 and installed GNU Make 4.3 Built for Windows32. This is my first time using GNU make and it gave me an error like this
.env:6: *** unterminated variable reference. Stop.
my .env file contain
POSTGRES_USER="postgres"
POSTGRES_PASS="<MY_DB_PASS>"
POSTGRES_DB="<MY_DB>"
PG_HOST="localhost"
PG_PORT="5432"
SECRET_KEY="<MY_SECRET_KEY>"
DEBUG=True
ALLOWED_HOSTS="localhost 127.0.0.1"
You may think that you're saving yourself by adding quotes. And, if this variable is parsed by a shell then you are.
But, make doesn't use quotes. The value of a variable is the complete contents to the right of the equal sign (after any initial whitespace is skipped). So for example:
POSTGRES_USER="postgres"
If parsed by the shell, the value of the POSTGRES_USER variable is postgres because the shell interprets the quotes. But make doesn't interpret quotes so the above line results in POSTGRES_USER make variable having the value "postgres" (including the quotes).
Now for your issue. Line 6 of your file is:
SECRET_KEY="<MY_SECRET_KEY>"
and you don't show us the text of your secret key.
First, this is wrong even in shell syntax: you must use single-quotes here not double quotes, and even that will not be right if your secret key contains single quotes itself; you'd have to escape that.
However that error means that in your secret key you have the character sequence $( or ${ which make interprets as starting a variable reference: since there is no close paren or brace you get this error.
The short answer is, there's no portable way to use the same file sourced by both make and the shell if the values of the variable assignments contain any sort of special character (including whitespace).
Usually people do something like base64 encode their secret keys, so that those special characters are not a problem.

Ruby Convert string into undescore, avoid the "/" in the resulting string

I have a name spaced class..
"CommonCar::RedTrunk"
I need to convert it to an underscored string "common_car_red_trunk", but when I use
"CommonCar::RedTrunk".underscore, I get "common_car/red_trunk" instead.
Is there another method to accomplish what I need?
Solutions:
"CommonCar::RedTrunk".gsub(':', '').underscore
or:
"CommonCar::RedTrunk".sub('::', '').underscore
or:
"CommonCar::RedTrunk".tr(':', '').underscore
Alternate:
Or turn any of these around and do the underscore() first, followed by whatever method you want to use to replace "/" with "_".
Explanation:
While all of these methods look basically the same, there are subtle differences that can be very impactful.
In short:
gsub() – uses a regex to do pattern matching, therefore, it's finding any occurrence of ":" and replacing it with "".
sub() – uses a regex to do pattern matching, similarly to gsub(), with the exception that it's only finding the first occurrence (the "g" in gsub() meaning "global"). This is why when using that method, it was necessary to use "::", otherwise a single ":" would have been left. Keep in mind with this method, it will only work with a single-nested namespace. Meaning "CommonCar::RedTrunk::BigWheels" would have been transformed to "CommonCarRedTrunk::BigWheels".
tr() – uses the string parameters as arrays of single character replacments. In this case, because we're only replacing a single character, it'll work identically to gsub(). However, if you wanted to replace "on" with "EX", for example, gsub("on", "EX") would produce "CommEXCar::RedTrunk" while tr("on", "EX") would produce "CEmmEXCar::RedTruXk".
Docs:
https://apidock.com/ruby/String/gsub
https://apidock.com/ruby/String/sub
https://apidock.com/ruby/String/tr
This is a pure-Ruby solution.
r = /(?<=[a-z])(?=[A-Z])|::/
"CommonCar::RedTrunk".gsub(r, '_').downcase
#=> "common_car_red_trunk"
See (the first form of) String#gsub and String#downcase.
The regular expression can be made self-documenting by writing it in free-spacing mode:
r = /
(?<=[a-z]) # assert that the previous character is lower-case
(?=[A-Z]) # assert that the following character is upper-case
| # or
:: # match '::'
/x # free-spacing regex definition mode
(?<=[a-z]) is a positive lookbehind; (?=[A-Z]) is a positive lookahead.
Note that /(?<=[a-z])(?=[A-Z])/ matches an empty ("zero-width") string. r matches, for example, the empty string between 'Common' and 'Car', because it is preceeded by a lower-case letter and followed by an upper-case letter.
I don't know Rails but I'm guessing you could write
"CommonCar::RedTrunk".delete(':').underscore

Change thing in the middle of the string notepad++

My file contains things like this:
http://example.com/main.do?y=yeay
http://example.com/main.do?y=hahahehe
http://example.com/main.do?d=wow
http://example.com/blah/blah/product.do?p=49302
etc...
I want to change them all like following.
http://example.com/main.do#y=yeay.html
http://example.com/main.do#y=hahahehe.html
http://example.com/main.do#d=wow.html
http://example.com/blah/blah/product.do#p=49302.html
These are the links in a html/do/asp files.
How can I change them? Thanks.
I can also use other programs not noteoad++ and i have both macOS and WIndows
THanks
Ctrl+H
Find what: https?\S+?\.do\K\?(\S+)
Replace with: #$1.html
UNCHECK Match case
CHECK Wrap around
CHECK Regular expression
UNCHECK . matches newline
Replace all
Explanation:
https? # http OR https
\S+? # 1 or more non spaces, not greedy
\. # a dot
do # literally "do"
\K # forget all we have seen until this position
\? # question mark
(\S+) # group 1, 1 or more non spaces
Replacement:
# # literally
$1 # content of group 1
.html # literally
Screenshot (before):
Screenshot (after):

How to gsub slash (/) to "" in ruby

To gsub / to "" ruby
I tried as,
ss = "http://url.com/?code=\#{code}"
I am fetching this url from database
then have to gsub \ to '' to pass the dynamic value in code
How to gsub \ to ''
required output
ss = "http://url.com/?code=#{code}"
Your problem is actually not a problem. When you write "http://url.com/?code=\#{code}" in ruby, \# means that ruby is escaping the # character, cause # is a protected character. So you should have the backslash to escape it.
Just to prove this, if you write in a console your string with single quotes (single quotes will escape any special character (but single quotes, of course)):
>> 'http://url.com/?code=#{code}'
=> "http://url.com/?code=\#{code}"
This may be a little obscure but, if you want to evaluate the parameter code in the string, you could do something like this:
>> code = 'my_code'
>> eval("\"http://url.com/?code=\#{code}\"")
=> "http://url.com/?code=my_code"
I believe what you may be asking is "how do I force Ruby to evaluate string interpolation when the interpolation pattern has been escaped?" In that case, you can do this:
eval("\"#{ss}\"")
If this is what you are attempting to do, though, I would highly discourage you. You should not store strings containing the literal characters #{ } in your database fields. Instead, use %s and then sprintf the values into them:
# Stored db value
ss = "http://url.com/?code=%s"
# Replace `%s` with value of `code` variable
result = sprintf(ss, code)
If you only need to know how to remove \ from your string, though, you can represent a \ in a String or Regexp literal by escaping it with another \.
ss.gsub(/\\/,'')
You can try in this way also, working fine for my case.
url = 'www.abc.com?user_id=#{user[:id]}'
uri = URI.parse(url.gsub("=\#", "="))
uri.query = URI.encode_www_form({user_id: 12})
puts uri.to_s ==> "www.abc.com?user_id=12"

Space delimited, except inside braces in a log file - Python

I'm a long time reader, first time asker (please be gentle).
I've been doing this with a pretty messy WHILE READ in Unix Bash, but I'm learning python and would like to try to make a more effective parser routine.
So I have a bunch of log files which are space delimited mostly, but contain square braces where there may also be spaces. How to ignore content within the braces, when looking for delimiters?
(I'm assuming that RE library is necessary to do this)
i.e. sample input:
[21/Sep/2014:13:51:12 +0000] serverx 192.0.0.1 identity 200 8.8.8.8 - 500 unavailable RESULT 546 888 GET http ://www.google.com/something/fsd?=somegibberish&youscanseethereisalotofcharactershere+bananashavealotofpotassium [somestuff/1.0 (OSX v. 1.0; this_is_a_semicolon; colon:93.1.1) Somethingelse/1999 (COMMA, yep_they_didnt leave_me_a_lot_to_make_this_easy) DoesanyonerememberAOL/1.0]
Desired output:
'21/Sep/2014:13:51:12 +0000'; 'serverx'; '192.0.0.1'; 'identity'; '200'; '8.8.8.8'; '-'; '500'; 'unavailable'; 'RESULT'; '546'; '888'; 'GET'; 'htp://www.google.com/something/fsd?=somegibberish&youscanseethereisalotofcharactershere+bananashavealotofpotassium'; 'somestuff/1.0 (OSX v. 1.0; this_is_a_semicolon; rev:93.1.1) Somethingelse/1999 (COMMA, yep_they_didnt leave_me_a_lot_to_make_this_easy DoesanyonerememberAOL/1.0'
If you'll notice the first and last fields (the ones that were in the square braces) still have spaces intact.
Bonus points
The 14th field (URL) is always in one of these formats:
htp://google.com/path-data-might-be-here-and-can-contain-special-characters
google.com/path-data-might-be-here-and-can-contain-special-characters
xyz.abc.www.google.com/path-data-might-be-here-and-can-contain-special-characters
google.com:443
google.com
I'd like to add an additional column to the data which includes just the domain (i.e. xyz.abc.www.google.com or google.com).
Until now, I've been taking the parsed output using a Unix AWK with an IF statement to split this field by '/' and check to see if the third field is blank. If it is, then return first field (up until the : if it is present), otherwise return third field). If there is a better way to do this--preferably in the same routine as above, I'd love to hear it--so my final output could be:
'21/Sep/2014:13:51:12 +0000'; 'serverx'; '192.0.0.1'; 'identity'; '200'; '8.8.8.8'; '-'; '500'; 'unavailable'; 'RESULT'; '546'; '888'; 'GET'; 'htp://www.google.com/something/fsd?=somegibberish&youscanseethereisalotofcharactershere+bananashavealotofpotassium'; 'somestuff/1.0 (OSX v. 1.0; this_is_a_semicolon; rev:93.1.1) Somethingelse/1999 (COMMA, yep_they_didnt leave_me_a_lot_to_make_this_easy DoesanyonerememberAOL/1.0'; **'www.google.com'**
Footnote: I changed http to htp in the sample, so it wouldn't create a bunch of distracting links.
The regular expression pattern \[[^\]]*\]|\S+ will tokenize your data, though it doesn't strip off the brackets from the multi-word values. You'll need to do that in a separate step:
import re
def parse_line(line):
values = re.findall(r'\[[^\]]*\]|\S+', line)
values = [v.strip("[]") for v in values]
return values
Here's a more verbose version of the regular expression pattern:
pattern = r"""(?x) # turn on verbose mode (ignores whitespace and comments)
\[ # match a literal open bracket '['
[^\]]* # match zero or more characters, as long as they are not ']'
\] # match a literal close bracket ']'
| # alternation, match either the section above or the section below
\S+ # match one or more non-space characters
"""
values = re.findall(pattern, line) # findall returns a list with all matches it finds
If your server logs have JSON in them you can include a match for curly braces as well:
\[[^\]]*\]|\{[^\}]*\}|\S+
https://regexr.com/

Resources