Finding substring of variable length in bash - string

I have a string, such as time=1234, and I want to extract just the number after the = sign. However, this number could be in the range of 0 and 100000 (eg. - time=1, time=23, time=99999, etc.).
I've tried things like $(string:5:8}, but this will only work for examples of a certain length.
How do I get the substring of everything after the = sign? I would prefer to do it without outside commands like cut or awk, because I will be running this script on devices that may or may not have that functionality. I know there are examples out there using outside functions, but I am trying to find a solution without the use of such.

s=time=1234
time_int=${s##*=}
echo "The content after the = in $s is $time_int"
This is a parameter expansion matching everything matching *= from the front of the variable -- thus, everything up to and including the last =.
If intending this to be non-greedy (that is, to remove only content up to the first = rather than the last =), use ${s#*=} -- a single # rather than two.
References:
The bash-hackers page on parameter expansion
BashFAQ #100 ("How do I do string manipulations in bash?")
BashFAQ #73 ("How can I use parameter expansion? How can I get substrings? [...])
BashSheet quick-reference, paramater expansion section

if time= part is constant you can remove prefix by using ${str#time=}
Let's say you have str='time=123123' if you execute echo ${str#time=} you would get 123123

Related

LUA -- gsub problems -- passing a variable to the match string isn't working [duplicate]

This question already has an answer here:
How to match a sentence in Lua
(1 answer)
Closed 1 year ago.
Been stuck on this for over a day.
I'm trying to use gsub to extract a portion of an input string. The exact pattern of the input varies in different cases, so I'm trying to use a variable to represent that pattern, so that the same routine - which is otherwise identical - can be used in all cases, rather than separately coding each.
So, I have something along the lines of:
newstring , n = oldstring:gsub(matchstring[i],"%1");
where matchstring[] is an indexed table of the different possible pattern matches, set up so that "%1" will match the target sequence in each matchstring[].
For instance, matchstring[1] might be
"\[User\] <code:%w*>([^<]*)<\\code>.*" -- extract user name from within the <code>...<\code>
while matchstring[2] could be
"\[World\] (%w)* .*" -- extract user name as first word after prefix '[World] '
and matchstring[3] could be
"<code:%w*>([^<]*)<\\code>.*" -- extract username from within <code>...<\code> at start
This does not work.
Yet when, debugging one of the cases, I replace matchstring[i] with the exact same string -- only now passed as a string literal rather than saved in a variable -- it works.
So.. I'm guessing there must be some 'processing' of the string - stripping out special characters or something - when it's sent as a variable rather than a string literal ... but for the life of me I can't figure out how to adjust the matchstring[] entries to compensate!
Help much appreciated...
FACEPALM
Thankyou, Piglet, you got me on the right track.
Given how this particular platform processes & passes strings, anything within <...> needed the escape character \ for downstream use, but of course - duh - for the lua gsub's processing itself it needed the standard %
much obliged

How to remove white spaces and capitalize every first letter in the string in the robotramework

How can I remove white spaces and capitalize every first letter in the string in the robotframework, so later I use the result in the Selenium library calls?
Test to Unlock the Service Account:
Open Browser ${URL} ${Browser}
${string_1} = get text ${question_1}
${temp_answer} = set variable ${string_1}.title()
${answer}= evaluate ${string_1}.replace(" ","")
Input Text ${Answer_1} ${answer}
sleep 5s
Input:
Legal business name
Output:
LegalBusinessName?
You were close to achieving it, but made two crucial mistakes. The first one is you used Set Variable and tried calling the python's title() string method in the argument - but that doesn't work for the keyword. It is a straightforward assignment - synonymous to the = operator; so what you ended up with as value was the string "Legal business name.title()". You should use the Evaluate keyword like in the second call, which does python's code eval.
The other mistake was to use two different variables - you store the capitalized version in the var ${temp_answer}, but then you don't remove the whitespace from it, but from the original one - ${string_1}. So even if the capitalization worked, you still wouldn't get the desired end result in the ${answer} var.
Here's a one-liner how to achieve what you need:
${answer}= evaluate """${string_1}""".title().replace(" ","")
The 2 methods are chained - replace() works on the result of title(), and the value of string_1 is in triple quotes so python works with its sting representation.

substitue string by index without using regular expressions

It should be very easy, but I am looking for an efficient way to perform it.
I know that I could split the string into two parts and insert the new value, but I have tried to substitute each line between the indexes 22-26 as follows:
line.replace(line[22:26],new_value)
The Problem
However, that function substitutes everything in the line that is similar to the pattern in line[22:26].
In the example below, I want to replace the marked number 1 with number 17:
Here are the results. Note the replacement of 1 with 17 in several places:
Thus I don't understand the behavior of replace command. Is there a simple explanation of what I'm doing wrong?
Why I don't want RE
The values between index 22-26 are not unified in form.
Note: I am using python 3.5 on Unix/Linux machines.
str.replace replaces 1 sub-string pattern with another everywhere in the string.
e.g.
'ab cd ab ab'.replace('ab', 'xy')
# produces output 'xy cd xy xy'
similarly,
mystr = 'ab cd ab ab'
mystr.replace(mystr[0:2], 'xy')
# also produces output 'xy cd xy xy'
what you could do instead, to replace just the characters in position 22-26
line = line[0:22] + new_value + line[26:]
Also, looking at your data, it seems to me to be a fixed-width text file. While my suggestion will work, a more robust way to process this data would be to read it & separate the different fields in the record first, before processing the data.
If you have access to the pandas library, it provides a useful function just for reading fixed-width files

what does this notation in hive script(hivequery.hql) file mean "use ${word:word}"

The script (hivequery.hql:) looks like this:
Use ${platformType:platformName};
select * from hivetablename;
And this script is being called in a bash script as
#!/usr/bin/env bash
hive -f hivequery.hql
Within an hql file, the use command sets the default database. See Use Database.
The ${platformType:platformName} is Hive's variable notation where platformType is the namespace and platformName is the variable name. This is explained in the Using Variables section of the Language Manual.
If you want to see what value a specific variable has, you can just use set like:
set platformType:platformName;
and it will print out the value. You can also run set; to get a full listing of known variables in all namespaces.
The more correct way to write the construct ${word:word} would be to write ${parameter:offset} . It cause parameter expansion, it expands to the portion of the value of parameter starting at the character (counting from 0 ) determined by expanding offset to the end of the parameter . It has one more variant as ${parameter:offset:length } - Expands to the portion of the value of parameter starting at the character (counting from 0 ) determined by expanding offset as an arithmetic expression and consisting of the number of characters determined by the arithmetic expression defined by length.
So I think basically the in your case , it is meant to get the name of the database from platformType.
For more details on this look into the
Look for Parameter Expansion in the bash man page.

Makefile macro modifier

I am totally confused about the following macro modifier in a Makefile I have come onto,
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
Here
TOOL_ROOTS=some filename prefixes
OBJDIR=$HOME/obj/
TOOL_SUFFIX=.so
Can someone tell me what this line actually means?
TOOL_ROOTS must be getting assigned some value other than the empty string at some point or that does nothing (which I'll show in a moment).
So first things first just expanding the variables takes us from:
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
to:
TOOLS = $(:%=~/obj%.so)
(which we can immediately see doesn't look right, and as I'll explain in a moment doesn't do anything)
So lets pretend it has a value instead.
TOOL_ROOTS = shovel axe hammer
And try the expansion again:
TOOLS = $(shovel axe hammer:%=~/obj%.so)
(That OBJDIR definition looks odd also. I would expect it to be ~/obj/ or something... and that's ignoring that ~ is a bad choice here and that $HOME would be much better.)
The next thing we need to know is what that syntax is all about. Well it is a Substitution Reference.
A substitution reference substitutes the value of a variable with alterations that you specify. It has the form ‘$(var:a=b)’ (or ‘${var:a=b}’) and its meaning is to take the value of the variable var, replace every a at the end of a word with b in that value, and substitute the resulting string.
When we say “at the end of a word”, we mean that a must appear either followed by whitespace or at the end of the value in order to be replaced; other occurrences of a in the value are unaltered. For example:
foo := a.o b.o c.o
bar := $(foo:.o=.c)
sets ‘bar’ to ‘a.c b.c c.c’. See Setting Variables.
A substitution reference is actually an abbreviation for use of the patsubst expansion function (see Functions for String Substitution and Analysis). We provide substitution references as well as patsubst for compatibility with other implementations of make.
Another type of substitution reference lets you use the full power of the patsubst function. It has the same form ‘$(var:a=b)’ described above, except that now a must contain a single ‘%’ character. This case is equivalent to ‘$(patsubst a,b,$(var))’. See Functions for String Substitution and Analysis, for a description of the patsubst function.
For example:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
sets ‘bar’ to ‘a.c b.c c.c’.
So, the first % there is matching the entirety of every word in the value of the variable (here shovel axe hammer) and then replacing each value with the expansion of the second part.
So shovel becomes ~/objshovel.so, etc. and we end up with:
TOOLS = ~/objshovel.so ~/objaxe.so ~/objhammer.so
See what I meant about OBJDIR being odd before? OBJDIR=~/obj/ would have left us with this instead:
TOOLS = ~/obj/shovel.so ~/obj/axe.so ~/obj/hammer.so
which makes a lot more sense to me.

Resources