How can I conditionally extract parts of a bash string. - bash

I have a bash string which looks like
TEST="tags/1.2.3-abc"
from which I want to extract the part after the slash, i.e. "1.2.3-abc" if and only if the string starts with the phrase "tags/". If the latter is not the case, I want to the string as it is.
Examples:
Input: tags/1.2.3-abc Output: 1.2.3-abc
Input: 1.2.3-abc Output: 1.2.3-abc
Input: trunk Output: trunk

Sounds like a job for the substitution operators in Bash.
Try something like:
TEST="tags/1.2.3-abc"
echo ${TEST#tags/}
You can read more about this syntax here: http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

Beside cut command you could also use bash string manipulation for your problem
TEST='tags/1.2.3-abc';
if test ${TEST#tags/*}; #Test that $TEST contains "tags/*" expression
then
TEST=${TEST:5}; #Re-assign to $TEST the substring after the "tags/"
fi

Related

How to remove a known last part from commands output string in one line?

To rephrase - I want to use Bash command substitution and string substitution in the same line.
My actual commands are longer, but the ridiculous use of echo here is just a "substitution" for shortness and acts the same - with same errors ;)
I know we can use a Bash command to produce it's output string as a parameter for another command like this:
echo "$(echo "aahahah</ddd>")"
aahahah</ddd>
I also know we can remove last known part of a string like this:
var="aahahah</ddd>"; echo "${var%</ddd>}"
aahahah
I am trying to write a command where one command gives a string output, where I want to remove last part, which is known.
echo "${$(echo "aahahah</ddd>")%</ddd>}"
-bash: ${$(echo "aahahah</ddd>")%</ddd>}: bad substitution
It might be the order of things happening or substitution only works on variables or hardcoded strings. But I suspect just me missing something and it is possible.
How do I make it work?
Why doesn't it work?
When a dollar sign as in $word or equivalently ${word} is used, it asks for word's content. This is called parameter expansion, as per man bash.
You may write var="aahahah</ddd>"; echo "${var%</ddd>}": That expands var and performs a special suffix operation before returning the value.
However, you may not write echo "${$(echo "aahahah</ddd>")%</ddd>}" because there is nothing to expand once $(echo "aahahah</ddd>") is evaluated.
From man bash (my emphasis):
${parameter%word}
Remove matching suffix pattern. The word is expanded to produce a
pattern just as in pathname expansion. If the pattern
matches a trailing portion of the expanded value of parameter, then
the result of the expansion is the expanded value of parameter
with the shortest matching pattern (the ''%'' case) or the longest matching pattern (the ''%%'' case) deleted.
Combine your commands like this
var=$(echo "aahahah</ddd>")
echo ${var/'</ddd>'}

Variable not getting assigned in bash after a curl hit

I have a shell script where I have a statement:
isPartial = $searchCurl| grep -Po '\"partialSearch\":(true|false)'|sed 's/\\\"partialSearch\\\"://'
now, if I just echo the RHS
$searchCurl| grep -Po '\"partialSearch\":(true|false)'|sed 's/\\\"partialSearch\\\"://'
it prints "partialSearch":true, but the variable isPartial doesn't get initialized .
Why is this happening and how can I fix it ?
Since the number of backslashes in your examples varies, it is not clear to me if the double quotes are already escaped in the input text. I’ll assume they are not, i.e. the input text looks something like:
sometext... "partialSearch":true ... sometext...
..bla bla bla... "partialsearch":false ...
and my examples below will work under this assumption.
There are a number of points to be made.
You seem to be trying to parse JSON input with regular expressions. While this could be acceptable for quick-and-dirty one-time jobs where you know the exact format of the data being processed, in general it is a very bad idea. You should use a JSON parser like jq.
You obviously have stored some bash code in the variable searchCurl. This is considered bad practice. Instead of searchCurl="... code ..." you should do function searchCurl () { ... code ... } and call searchCurl without prefixing it with a dollar sign. Variables are for values, functions are for code.
In most cases, if you are going to use sed, it’s better to use it for everything without invoking grep. Sometimes it can be simpler to have both. See below for an example.
To assign the output of a command to a variable, you have to use command substitution.
In short, if in your input text you have only one match of '"partialSearch":(true|false)', this is what you want:
isPartial=$(searchCurl|sed -rn 's/^.*"partialSearch":(true|false).*$/\1/p')
If you have more and the input text is one big line as I suppose, usage of grep -o might simplify the task of splitting the input into one match per line, so that
isPartial=$(searchCurl|grep -Po '"partialSearch":(true|false)'|sed -e 's/^.*://')
might be what you want (and in this case, isPartial will hold a space-separated list of true and false).

Remove part of a string using KornShell

I have this string DFUB1AG.T1310LC.C140206.XIYG000.FCIPHE31 and I need to remove the first part of it. How can I do this?
As has been asked here is what I want to achieve.
Want to get this string that is separated by "."
DFUB1AG.T1310LC.C140206.XIYG000.FCIPHE31
And want to remove the first part of it to get the result as below
T1310LC.C140206.XIYG000.FCIPHE31
I have already achieved it by doing this way:
Okay guys I got it done by doing this.
# var=DFUB1AG.T1310LC.C140206.XIYG000.FCIPHE31
# var=${var#*.}
# echo $var
# T1310LC.C140206.XIYG000.FCIPHE31
If STRING is your variable, and you want to strip everything before first dot you can say STRING=${STRING#*.} ........Removes shortest match at beginning of string of any character followed by a dot.
echo "$VarWithYourString" | sed "s/^[^.]\{1,\}./"
or
sed "s/^[^.]\{1,\}./" YourFileInput

string handling in bash

the problem I met is like this:
given a string dimensioning-inspection_depth-0rules_20120306-084158
I'd like to get the first part of the string: dimensioning-inspection_depth-0rules, so to speak, get rid of the time stamp part. In perl, it's like a piece of work to do the job using regular expression. But since I'm new to bash, I'd like to know
the best-practice way of doing it in Bash.
If you don't want to pipe the string to sed, you can use Bash variable mangling:
$ string=dimensioning-inspection_depth-0rules_20120306-084158
$ echo ${string%_*}
dimensioning-inspection_depth-0rules
More information on variable mangling here.
You can do this:
str=dimensioning-inspection_depth-0rules_20120306-084158
echo ${str%_*}
This will remove anything after and including the last _ in the string, so if your string always has the form something_date-time, you will always be left with something part.
More info here:
http://tldp.org/LDP/abs/html/string-manipulation.html
a="dimensioning-inspection_depth-0rules_20120306-084158"
echo $a | head -c -16
So as the timestamp will always be equal width (16 characters that you are trying to trim off the end in this case), head -c -16 should work for you

Search and replace in Shell

I am writing a shell (bash) script and I'm trying to figure out an easy way to accomplish a simple task.
I have some string in a variable.
I don't know if this is relevant, but it can contain spaces, newlines, because actually this string is the content of a whole text file.
I want to replace the last occurence of a certain substring with something else.
Perhaps I could use a regexp for that, but there are two moments that confuse me:
I need to match from the end, not from the start
the substring that I want to scan for is fixed, not variable.
for truncating at the start: ${var#pattern}
truncating at the end ${var%pattern}
${var/pattern/repl} for general replacement
the patterns are 'filename' style expansion, and the last one can be prefixed with # or % to match only at the start or end (respectively)
it's all in the (long) bash manpage. check the "Parameter Expansion" chapter.
amn expression like this
s/match string here$/new string/
should do the trick - s is for sustitute, / break up the command, and the $ is the end of line marker. You can try this in vi to see if it does what you need.
I would look up the man pages for awk or sed.
Javier's answer is shell specific and won't work in all shells.
The sed answers that MrTelly and epochwolf alluded to are incomplete and should look something like this:
MyString="stuff ttto be edittted"
NewString=`echo $MyString | sed -e 's/\(.*\)ttt\(.*\)/\1xxx\2/'`
The reason this works without having to use the $ to mark the end is that the first '.*' is greedy and will attempt to gather up as much as possible while allowing the rest of the regular expression to be true.
This sed command should work fine in any shell context used.
Usually when I get stuck with Sed I use this page,
http://sed.sourceforge.net/sed1line.txt

Resources