What is the use of Percent-S (%s) at the end of strings? (Not string formatting) - string-formatting

I'm trying to configure the browser for Jupyter Notebook, and in the .jupyter config file, I am confused by this line.
What is the point of %s at the end of the string?
c.NotebookApp.browser = u'open -a chrome.exe %s'
When I search for %s in strings on the internet, I get the pages related to string formatting (where the string is followed by an additional % variable, to substitute the variable into the string). This is totally unrelated isn't it?

The string is likely passed to sprintf(), which inserts a string parameter in place of %s. See man printf.
In this case, the URL in inserted as a parameter for the open command.
The author of the config file format decided to use string formatting here, so you can insert the URL parameter anywhere in the string, and not only at the end of it, i.e.:
c.NotebookApp.browser = u'/usr/bin/my_browser -new -url %s -some -more -parameters'
Then at runtime of the application, the URL parameter is injected with string formatting:
shellCmd = config.NotebookApp.browser % targetUrl
It is important. Don't delete it.

Related

Split array element delimited with '.'

I am trying to read below CSV file content line by line in Perl.
CSV File Content:
A7777777.A777777777.XXX3604,XXX,3604,YES,9
B9694396.B216905785.YYY0018,YYY,0018,YES,13
C9694396.C216905785.ZZZ0028,ZZZ,0028,YES,16
I am able to split line content using below code and able to verify the content too:
#column_fields1 = split(',', $_);
print $column_fields1[0],"\n";
I am also trying to find the second part on the first column of CSV file (i.e., A777777777 or B216905785 or C216905785) – the first column delimited with . using the below code and I am unable to get it.
Instead, just a new line printed.
my ($v1, $v2, $v3) = split(".", $column_fields1[0]);
print $v2,"\n";
Can someone suggest me how to split the array element and get the above value?
On my functionality, I need the first column value altogether at someplace and just only the second part at someplace.
Below is my code:
use strict;
use warnings;
my $dailybillable_tab_section1_file = "./sql/demanding_01_T.csv";
open(FILE, $dailybillable_tab_section1_file) or die "Could not read from $dailybillable_tab_section1_file, program halting.";
my #column_fields1;
my #column_fields2;
while (<FILE>)
{
chomp;
#column_fields1 = split(',', $_);
print $column_fields1[0],"\n";
my ($v1, $v2, $v3) = split(".",$column_fields1[0]);
print $v2,"\n";
if($v2 ne 'A777777777')
{
…
…
…
}
else
{
…
…
…
}
}
close FILE;
split takes a regex as its first argument. You can pass it a string (as in your code), but the contents of the string will simply be interpreted as a regex at runtime.
That's not a problem for , (which has no special meaning in a regex), but it breaks with . (which matches any (non-newline) character in a regex).
Your attempt to fix the problem with split "\." fails because "\." is identical to ".": The backslash has its normal string escape meaning, but since . isn't special in strings, escaping it has no effect. You can see this by just printing the resulting string:
print "\.\n"; # outputs '.', same as print ".\n";
That . is then interpreted as a regex, causing the problems you have observed.
The normal fix is to just pass a regex to split:
split /\./, $string
Now the backslash is interpreted as part of the regex, forcing . to match itself literally.
If you really wanted to pass a string to split (I'm not sure why you'd want to do that), you could also do it like this:
split "\\.", $string
The first backslash escapes the second backslash, giving a two character string (\.), which when interpreted as a regex means the same thing as /\./.
If you look at the documentation for split(), you'll see it gives the following ways to call the function:
split /PATTERN/,EXPR,LIMIT
split /PATTERN/,EXPR
split /PATTERN/
split
In three of those examples, the first argument to the function is /PATTERN/. That is, split() expects to be given a regular expression which defines how the input string is split apart.
It's very important to realise that this argument is a regex, not a string. Unfortunately, Perl's parser doesn't insist on that. It allows you to use a first argument which looks like a string (as you have done). But no matter how it looks, it's not a string. It's a regex.
So you have confused yourself by using code like this:
split(".",$COLUMN_FIELDS1[0])
If you had made the first argument look like a regex, then you would be more likely to realise that the first argument is a regex and that, therefore, a dot needs to be escaped to prevent it being interpreted as a metacharacter.
split(/\./, $COLUMN_FIELDS1[0])
Update: It's generally accepted among Perl programmers, that variable with upper case names are constants and don't change their values. By using upper case names for standard variables, you are likely to confuse the next person who edits your code (who could well be you in six months time).

Batch file dropping characters

I'm creating a simple batch file that uses Azure REST API to download data from a blob. If I type the request directly into the command prompt, it works perfectly and my data appears in the directory. However, when I run it as a batch file, it does not work and I can see in the command line that some characters from the blob connection string (acts as an access token) have been dropped. I cannot share the full access token, but can show that the drop happens at the end of the connection string, in what is known as the signature:
correct: "...5U%2BJgo%3D"
batch file output: "...5UBJgoD"
It appears the issue is with special characters and some numbers. There are no other special characters in the signature and other numbers in the rest of the signature are not affected.
Other notes:
The connection string is indeed entered within a "" string
I tried forcing the encoding to UTF-8 encoding by running chcp 65001 before the request line executes; didn't work
You should escape your percent sign (%) with double-percent sign (%%). For example you should type:
"...5U%%2BJgo%%3D"
It is quite useful to search in the internet before you post here, on Stack OverFlow. So, check the links provided:
http://www.robvanderwoude.com/escapechars.php
https://ss64.com/nt/syntax-esc.html
Special Characters in Batch File
Hope this helps!

SSIS : Unwanted line return on a dynamic connection string

In a SSIS package, I want to send data from several instance to a flat files. To do so I create a dynamic connection string made of 3 variables:
".txt"
a Network path
The file name (which is the instance Name variable (string) that i use elsewhere in my package)
When i evaluate my expression at this point i receive :
For
TRIM(#[User::FileName]+REPLACE(#[User::ServerName],"\\","")+#[User::ExtensionFile])
I receive
\\test-01\TEMP\SQL01MyInstance.txt
But, when i run the job, it's unable to create the SQL01MyInstance.txt, and i receive as error :
[Flat File Destination [11]] Error: Cannot open the datafile "\\test-01\TEMP\SQL01MyInstance
.txt".
[SSIS.Pipeline] Error: Flat File Destination failed the pre-execute phase and returned error code 0xC020200E.
There's a unwanted space at the end filename, when i copy paste the error message elsewhere it appear to be a line return (before the .txt)
Does anybody know how can i get rid of it that line return (which i'm assuming is making the job fail) ?
Edit 1:
Rights on the destination folder are ok, because there's another flat file that I create in case of errors and it's created normally after that failure; but not with a dynamic name (normal behavior)
To remove line return you can use REPLACE() function with \r\n
REPLACE(REPLACE(TRIM(#[User::FileName]+REPLACE(#[User::ServerName],"\\","")+#[User::ExtensionFile]),"\r",""),"\n","")
Where
\r : carriadge return
\n : line feed
The TRIM function only trims the space character (versus other functions which trim all white space):
TRIM does not remove white-space characters such as the tab or line feed characters. Unicode provides code points for many different types of spaces, but this function recognizes only the Unicode code point 0x0020. When double-byte character set (DBCS) strings are converted to Unicode they may include space characters other than 0x0020 and the function cannot remove such spaces. To remove all kinds of spaces, you can use the Microsoft Visual Basic .NET Trim method in a script run from the Script component.
https://learn.microsoft.com/en-us/sql/integration-services/expressions/trim-ssis-expression
You can try this first to see if it works (Trim first then concatenate):
TRIM(#[User::FileName]) + TRIM(REPLACE(#[User::ServerName],"\","")) + TRIM(#[User::ExtensionFile]))
If not then you'll have to do the recommended String.Trim() function using a Script Task/Component that the MSDN article recommends (again, Trim each variable first, then concatenate)

How do you ignore known words in sscanf?

I'm trying to strip the data from a string, something like this:
char * fromSocket = "GET /test.html HTTP 1.0\n""Host: www.example.com\n""Client: 127.0.0.1:60000\n";
Where I know that, in this case "HTTP 1.0" "Host:" and "Client" and the semicolon between the client IP and the port will always be there. I'm trying to use a sscanf() like this:
sscanf(conString, "%s %s HTTP 1.0 Host: %s Client: %s:%s", com, loc, hos, cli, port);
But when I test the outputs using this:
printf("%s %s %s %s %s\n", com, loc, hos, cli, port);
I get a bunch of NULLs. How do I ignore the specific words that I know will exist? I looked at some of the pages online, but I think the 1.0 throws the scanner off or whatever. Thanks!
You just put those parts into your format string, and sscanf will assure they're present and accounted for, but won't read them into any variable. For example:
sscanf("GET /test.html HTTP 1.0\nHost: www.example.com\nClient: %16[^:]:%d\n", cli, port);
Also note that white-space (outside a scan-set) in a scanf format string is treated a bit differently from other characters--instead of matching the specified character, it will match an arbitrary amount of white space (so, for example, "\n" in the format string can match " \t\v \r" in the input data). As such, if you need to verify that the new-lines are really new-lines (and not other white-space) you need to change them to something like %*[\n]. If you do that, keep in mind that the norm for most network protocols is a "\r\n" sequence.
If your real question is how to allow (for example) the www.example.com to be an arbitrary string, and you want to assure there's a string there, but don't want to read it into a variable, then you can use a conversion with a * to read but prevent conversion, like: %*s:
sscanf("GET %*s HTTP 1.0\nHost: %*s\nClient: %16[^:]:%d\n", cli, port);

Parsing multiline string in C

I'm trying to parse a file using C language with a format like this:
FILE, "CONTENT", PATH
So, for example I have an input like this:
file.txt, "This is a simple file", /home/user
config.txt, "#Used to do any configurations
#ID = 'PC1'
VERSION = 1.25", /etc
First, I read a line of the file an put it into buffer, next I do:
sscanf(buffer, "%[^,], \"%[^\"]\", %s", name, content, path)
But, however I only get correctly single line inputs. Is there a way to force sscanf to accept new lines on CONTENT string?
For non-trivial parsing, I would tecommend using Flex and Bison

Resources