Remove part of a string using KornShell - shell

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

Related

BASH - Replace substring "$$" with substring "$$$"

Essentially what I am trying to do is take a string with a bunch of text and if it has a substring of "$$" to replace it with a substring of "$$$"
ex:
string="abcde\$\$fghi"
# Modify string
echo $string
# ^ should give "abcde$$$fghi"
I have been at this for like 2 hours now and it seems like a very simple thing, so if anyone could provide some help then I would greatly appreciate it. Thanks!
EDIT: Changed original string in the question from "abcde$$fghi" to "abcde\$\$fghi"
$$ is a special variable in the shell, it contains the ID of the current process. The variables are expanded in double quotes, therefore string does not contain $$ but a number (the PID of shell) instead.
Enclose the string in apostrophes (single quotes) to get $$ inside it.
The replacement you need can be done in multiple ways. The simplest way (probably) and also the fastest way (for sure) is to use / in the parameter expansion of $string:
echo "${string/'$$'/'$$$'}"
To make it work you have to use the same trick as before: wrap $$ and $$$ in single quotes to prevent the shell replace them with something else. The quotes around the entire expression are needed to preserve the space characters contained by $string, otherwise the line is split to words by whitspaces and and echo outputs these words separated by one space character.
Check it online.
If you quote the string with single quote marks (i.e. string='abcde$$fghi') you can do the replacement with echo "${string/'$$'/'$$$'}"
Edit: this is basically what #axiac said in their comment

Extract a substring (value of an HTML node tag) in a bash/zsh script

I'm trying to extract a tag value of an HTML node that I already have in a variable.
I'm currently using Zsh but I'm trying to make it work in Bash as well.
The current variable has the value:
<span class="alter" fill="#ffedf0" data-count="0" data-more="none"/>
and I would like to get the value of data-count (in this case 0, but could be any length integer).
I have tried using cut, sed and the variables expansion as explained in this question but I haven't managed to adapt the regexs, or maybe it has to be done differently for Zsh.
There is no reason why sed would not work in this situation. For your specific case, I would do something like this:
sed 's/.*data-count="\([0-9]*\)".*/\1/g' file_name.txt
Basically, it just states that sed is looking for the a pattern that contains data-count=, then saves everything within the paranthesis \(...\) into \1, which is subsequently printed in place of the match (full line due to the .*)
Could you please try following.
awk 'match($0,/data-count=[^ ]*/){print substr($0,RSTART+12,RLENGTH-13)}' Input_file
Explanation: Using match function of awk to match regex data-count=[^ ]* means match everything from data-count till a space comes, if this regex is TRUE(a match is found) then out of the box variables RSTART and RLENGTH will be set. Later I am printing current line's sub-string as per these variables values to get only value of data-count.
With sed could you please try following.
sed 's/.*data-count=\"\([^"]*\).*/\1/' Input_file
Explanation: Using sed's capability of group referencing and saving regex value in first group after data-count=\" which is its length, then since using s(substitution) with sed so mentioning 1 will replace all with \1(which is matched regex value in temporary memory, group referencing).
As was said before, to be on the safe side and handle any syntactically valid HTML tag, a parser would be strongly advised. But if you know in advance, what the general format of your HTML element will look like, the following hack might come handy:
Assume that your variable is called "html"
html='<span class="alter" fill="#ffedf0" data-count="0" data-more="none"/>'
First adapt it a bit:
htmlx="tag ${html%??}"
This will add the string tag in front and remove the final />
Now make an associative array:
declare -A fields
fields=( ${=$(tr = ' ' <<<$htmlx)} )
The tr turns the equal sign into a space and the ${= handles word splitting. You can now access the values of your attributes by, say,
echo $fields[data-count]
Note that this still has the surrounding double quotes. Yuo can easily remove them by
echo ${${fields[data-count]%?}#?}
Of course, once you do this hack, you have access to all attributes in the same way.

Appending string to the variable

I read some file line by looking for some specific string. When I find I assign it to the var.
But when I try to append to that string I have problem. Instead of add to the end of var i get var where characters at the beginning are replaced by new characters.
Example:
echo $fileToGet
newVar=$fileToGet".xml"
echo $newVar
Output:
c024z160205
.xmlz160205
And what I want is: c024z160205.xml
I think I tried everything what is on Stack, several ways of appending but nothing works.
The problem was \r at the end of var. Before assigning line to var fileToGet I do something like:
newVar=$(echo "$fileToGet" | tr -d '\r')
and after concatenation I have what I want.
I edit this answer because it contains false informations. What really was the problem #chepner described in comment: 'The terminal simply displays any characters following the carriage return at the beginning of the line, overwriting the earlier characters.'
Thanks!
Your code is working for me, try using:
newVar="${fileToGet}.xml"
Instead of newVar=$fileToGet".xml"; you gotta put the variable also inside the quotes.
Tell me if it works now.

Caseinsensitive Parameter Expansion

my problem is, I try to strip a string at a start of a variable. I have done shopt -s exglob to get extended pattern matching.
a="HelloDolly"
echo "${a#[A-Z]+([a-z])}"
I thought that +([a-z]) mean as much lower case letter as possible. And that [A-Z]+([a-z]) should match Hello
should return Dolly but I get lloDolly back. If give / instead # a try
echo "${a/[A-Z]+([a-z])}"
I get back nothing. Looks like the Parameter Expansions is caseinsensitive.
Thanks everybody who could give me an hint.
Using a single #, you get the shortest possible match. "He" is the shortest possible match of one uppercase letter and one or more lowercase letters. Switch to double # to get the longest possible match "Hello"
echo "${a##[A-Z]+([a-z])}"
To avoid issues with locale-based interpretation of character ranges, use character classes instead:
echo "${a##[[:upper:]]+([[:lower:]])}"

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