I am writing a bash script which updates a mongo document. If it's a new document then it creates a new document in mongo else updates it.
I want to pass bash array variable to the mongo query since few fields are of array type. I am not sure how to pass the array field. Any help would be appreciated.
This is my query:
db.my_col.update({emp_id: '"'$emp_id'"'}, {$set: {contacts: '"'${contacts}'"', emp_name: '"'$emp_name'"'}}, {upsert: true})
If I just add like normal variable the only first value in variable gets added.
If you put your array variable into a string, only the first item will be there, right
Basically, you get all of them with this syntax ${contacts[#]}, but they will be unquoted and separated with spaces and likely won't work in a query because of wrong syntax.
So you'd need to manually convert a Bash array to a JS array. I don't know an automagical way to do it, but consider this function:
function jsarray {
res=""
for a in ${#}; do
res="$res,\"$a\""
done
echo [ ${res:1} ]
}
It goes through it's arguments, wraps each one in quotes and joins together with commas.
Use it like this (I assume $contacts is an array of string values):
IFS=""
contacts=("skype name" "email address" phone website whatever)
jscontacts=$(jsarray $contacts[#])
# Proceed to using $jscontacts in your query.
After that $jscontacts will be a string value of [ "skype name","email address","phone","website","whatever" ].
Notes:
IFS="" - IFS stands for internal field separator, this is how Bash separates arguments from each other. By default it's " " (a space). Resetting it to nothing to preserve array items with spaces in them; otherwise "skype name" beŃome two separate values of "skype" & "name".
${res:1} - skips the first character from $res (because it's a comma).
jscontacts=$(...) captures the terminal output into a jscontacts variable.
Related
I'm sure this is somewhere on here but I can't seem to find it. I'm trying to pull a document from a large file that only matches an exact term in a field, as opposed to anything with those letters in it.
More precisely, I'm trying to use .find({"name":"Eli"}) to pull the documents with that name, but my search is pulling every name with those letters (such as elizabeth or ophelia)
You can use a regular expression match to make sure you do not return names that share the same character formation.
Something like this:
const name = "Eli"
const query = new RegExp(`^${name}$`)
const user = await Collection.find({ name: { $regex: query } })
I am using 2 key operators from RegEx here: ^ and $
Putting ^ in front of a regular expression will match all strings that start with the pattern given.
Putting $ at the end of a regular expression will match all strings that end with the pattern given.
So essentially you are asking mongoose to find the record where the name both begins and ends with Eli. This will prevent Elizabeth from showing up in your result, but won't filter out other Eli's.
Is it possible to use a variable in the "Request body" field in a Copy data activity?
This is my pipeline:
Output of "Get requestBody":
Allready full of unwanted slashes.
Output of "Set variable":
I using this expression in the "Request body" Field:
#replace(variables('requestBody'),'\','')
This is the input of "Copy data":
I cant get rid of all slashes. Is it even possible to use a variable for "Request body"?
As your lookup activity output returns JSON string value it includes an escape character backslash '\'.
To remove the escape character, create an array type variable and convert the lookup out to JSON array in append variable activity as below.
Create array variable.
Lookup output: As I checked firstrow only property in lookup activity, the output results firstrow only.
In the Append variable activity, get the lookup output and convert it to JSON array.
#json(activity('Lookup1').output.firstrow.requestbody)
Append variable result: Use this variable in later activities.
You can refer to these SO & SO threads for reference.
To remove the backslashes, I had to use this:
#replace(string(variables('requestBody')), '\"', '"')
I'm trying to add multiple strings to the -DescriptiveText property of a single resource record using the command as shown in the docs here:
# a,b,c,d in the following are different items separated by `r`n
Add-DNSServerResourceRecord -DescriptiveText "a`r`nb`r`nc`r`nd" -Name "identifier" -Txt -ZoneName $ZONE -ZoneScope $ZONE_SCOPE -TimeToLive 0:1:0:0
I know the expected return value of another command that retrieves this data results in the following:
TXT
"a"
"b"
"c"
"d"
However the above returns the following which doesn't work
TXT
"a
b
c
d"
I have tried other methods as follows including:
Trying arrays like "a","b","c","d" as referenced in the accepted answer here which errored
Other methods of formatting the string to match the expected output involving adding missing quotes marks to try and align it with the expected return value
Tried calling the command with each individual part which made multiple records with the required data but didn't work as it needs to be in one record
Any advice on how to do it would be appreciated. Thanks :)
Txt records can have multiple strings and/or multiline strings. It looks like your other command is expecting the former.
Unfortunately, the Add-DnsServerResourceRecord cmdlet only accepts a single string for the DescriptiveText. `r`n only adds a newline to that single string, which is why your tool isn't processing them as separate entries.
Instead, use dnscmd:
dnscmd.exe servername /recordadd example.com identifier TXT "a" "b" "c"
A similar annoyance is that Get-DnsServerResourceRecord will only return the first string of a text record as well.
If I want to queue a build using AzureDevops with overwritten variables, I have to pass a parameters string:
{ "definition" : { "id" : [BUILD_ID] },
"parameters" : str(variables_to_overwrite)
}
where variables_to_overwrite is a dictionary like so:
variables_to_overwrite = {
"list_1" : str( ['A', 'B', 'C'] )
"list_2" : str( ['D', 'E'] )
}
If I don't cast these lists as strings, the build will not queue. I print out params before queuing the build and they look correct:
{'definition': {'id': [BUILD_ID},
'parameters': '{\'list_1\': "\'[\'A\', \'B\', \'C\']\'", \'list_2\': "\'[\'D\', \'E\']\'}'
but when I have the build print out the arguments it sees, it prints:
'--list_1', "'['A", "B',", "'C"]'", '--list_2', "'['D", "E']'"
As you can see, the single and double quotes have become quite mixed up, which means programs that parse args don't see this as two args, but seven!
I tried force-replacing all the double quotes with single quotes, but when I do that, the build won't queue. I even tried rewriting it like so:
{'definition': {'id': [BUILD_ID},
'parameters': '{\'list_1\': \'[\'A\', \'B\', \'C\']\', \'list_2\': \'[\'D\', \'E\']\'}'
But when I get back the build result, it has done the same thing of adding in double-quotes mixed up with single quotes (in exactly the same way as previously described).
How can I prevent DevOps from destroying the quote pairing in things like lists and dicts that are passed as parameters? I have tried every permutation I can think of, including manually wrapping it in quotes, replacing quotes, using json.dumps, etc. Nothing works. The only way to get the build to queue is to pass a string, and no matter what quote inputs it gets, whether escaped or not, devOps goes through and replaces all quotes with a single-quote, double-quote pattern.
After lengthy trial and error, I determined that Azure DevOps requires that lists intended for overwriting have this format:
'[]',
'"[\'A\', \'B\']"'
That is to say, single-quote, double-quote, bracket, escaped single quotes inside the list, bracket, double-quote, single-quote. Quote styles cannot be interchanged and the escape character is required. Any deviation will result in the problem described in the question.
This is pretty much impossible to do in Python using str(). However, it can be done using repr().
When defining variables_to_overwrite, do not cast any lists to string (as the question shows). Instead, leave them as lists and then perform the following sort of replacement:
if variables_to_overwrite:
for key in variables_to_overwrite:
value = variables_to_overwrite[key]
if type(value) == list:
variables_to_overwrite[key] = '"' + repr(value) + '"' # THIS FORMAT IS CRUCIAL
Finally, define your parameters:
params = {
"definition": {
"id": build_id
},
"parameters" : str(variables_to_overwrite) # THIS IS THE ONLY PLACE TO USE STR()
}
This will convert the list into the weird string format Azure DevOps requires and prevent DevOps from mangling the quotes.
I have a line saved as $variable1, for example:
file"yourtxthere/i/master.ext" autostart:true, width
How would I go about writing the correct syntax using Regex in Powershell to grab everything within the quotes. Are regular expressions the best way to do this in Powershell?
Though regular expressions are powerful, this is a simple case. Thus a simple solution is based on string object's split() method.
$variable1 = 'file"yourtxthere/i/master.ext" autostart:true, width'
# Splitting requires at least one "
if ($variable1.IndexOf('"') -gt 0) {
$variable1.Split('"')[1]
}
Splitting the string will result an array of three elements:
file
yourtxthere/i/master.ext
autostart:true, width
As Powershell's arrays begin with index zero, the desired data is at index location 1. In case the string doesn't contain a double quote, the split won't work. This is checked with the statement
if ($variable1.IndexOf('"') -gt 0)
Without one, splitting a quoteless string would return just a one-celled array and trying to access index 1 would result in an error message:
$variable1.Split('!')[1]
Index was outside the bounds of the array.
I'm not 100% sure I understand the question but assuming you had that stored in $variable1 as a string like so:
$variable1 = 'file"yourtxthere/i/master.ext" autostart:true, width'
Then you could extract just the quoted text by splitting the string using the double quotes as a delimiter like this:
$variable1.Split('"')[1]
That splits the string into an array with three parts. The first part is everything before the first double quotes and the second everything in between the first and second quote marks, and the third everything after the second quotation marks. The [1] tells it to output the second part.
I think this picture might illustrate it a little better.
There are other ways to split that up and in fact the variable isn't necessary at all if you do something like this:
('file"yourtxthere/i/master.ext" autostart:true, width').split('"')[1]
That will work fine so long as there are never any extra double quotes before the first occurrence.