How to extract hostname from OCS ID - bash

I'm fixing a bash script on GLPI that displays machines that have not been updated for more than a month. Data in are displayed like this :
myhostname01t-2015-03-09-16-47-42
I'd like, through regex, get only the name : myhostname01t
I've created this regex :
(.*)-([0-9]{4}.*)
With sed how could i get only the name ?

Simple cut isn't enough? Easier to comprehend than sed.
echo 'myhostname01t-2015-03-09-16-47-42' | cut -d'-' -f1

Since you asked for sed:
$ S="myhostname01t-2015-03-09-16-47-42"
$ sed 's/\(^[^-]\+\).*/\1/' <<<$S
myhostname01t
or even simpler with awk:
$ awk -F- '{print $1}' <<<$S
myhostname01t
Perl:
$ perl -F- -lane 'print $F[0]' <<<$S
myhostname01t

If the aim is to extract the hostname from an OCS ID stored in one variable and put it in another variable then it can be done with pure Bash code:
ocsid='parta-1234-partb-2015-03-09-16-47-42'
hostname=${ocsid%-*-*-*-*-*-*}
printf 'hostname=%s\n' "$hostname"
See Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?)) for an explanation of ${ocsid%-*-*-*-*-*-*}.

Related

One-liner POSIX command to lowercase string in bash

Problem
I have this comand:
sed $((SS - default_scripts))!d customScripts.txt
and it gives me Foo Bar.
I want to convert this to lowercase.
Attempt
When I tried using the | awk '{print tolower($0)}' command on it it returned nothing:
$($(sed $((SS - default_scripts))!d customScripts.txt) | awk '{print tolower($0)}')
Final
Please enlighten me on my typo, or recommend me another POSIX way of converting a whole string to lowercase in a compact manner. Thank you!
The pipe to awk should be inside the same command substitution as sed, so that it processes the output of sed.
$(sed $((SS - default_scripts))!d customScripts.txt | awk '{print tolower($0)}')
You don't need another command substitution around both of them.
Your typo was wrapping everything in $(...) and so first trying to execute the output of just the sed part and then trying to execute the output of the sed ... | awk ... pipeline.
You don't need sed commands nor shell arithmetic operations when you're using awk. If I understand what you're trying to do with this:
$(sed $((SS - default_scripts))!d customScripts.txt) | awk '{print tolower($0)}'
correctly then it'd be just this awk command:
awk -v s="$SS" -v d="$default_scripts" 'BEGIN{n=s-d} NR==n{print tolower($0); exit}' customScripts.txt

extract string between '$$' characters - $$extractabc$$

I am working on shell script and new to it. I want to extract the string between double $$ characters, for example:
input:
$$extractabc$$
output
extractabc
I used grep and sed but not working out. Any suggestions are welcome!
You could do
awk -F"$" '{print $3}' file.txt
assuming the file contained input:$$extractabc$$ output:extractabc. awk splits your data into pieces using $ as a delimiter. First item will be input:, next will be empty, next will be extractabc.
You could use sed like so to get the same info.
sed -e 's/.*$$\(.*\)$$.*/\1/' file.txt
sed looks for information between $$s and outputs that. The goal is to type something like this .*$$(.*)$$.*. It's greedy but just stay with me.
looks for .* - i.e. any character zero or more times before $$
then the string should have $$
after $$ there'll be any character zero or more times
then the string should have another $$
and some more characters to follow
between the 2 $$ is (.*). String found between $$s is given a placeholder \1
sed finds such information and publishes it
Using grep PCRE (where available) and look-around:
$ echo '$$extractabc$$' | grep -oP "(?<=\\$\\$).*(?=\\$\\$)"
extractabc
echo '$$extractabc$$' | awk '{gsub(/\$\$/,"")}1'
extractabc
Here is an other variation:
echo "$$extractabc$$" | awk -F"$$" 'NF==3 {print $2}'
It does test of there are two set of $$ and only then prints whats between $$
Does also work for input like blabla$$some_data$$moreblabla
How about remove all the $ in the input?
$ echo '$$extractabc$$' | sed 's/\$//g'
extractabc
Same with tr
$ echo '$$extractabc$$' | tr -d '$'
extractabc

Using Bash to delete a bracket delimited substring from string variable

I have this string in a variable:
strVar="Hello World [randomSubstring].zip"
I would like to extract [randomSubstring], where that substring inside the brackets could be anything.
The expected result must be something like this:
echo "$strVar"
Hello World .zip
I tried several combinations with grep and awk but without success, I am using CentOS 7.
echo "Hello World [RNVE5Z].zip" | grep -oP '(?<=[).*(?=])'
echo "Hello World [RNVE5Z].zip" | awk -F"["" '{print $1}' | awk -F"]" '{print $2}'
Bash only:
echo ${strVar/\[*\]/}
Just use bash's substring manipulation:
echo ${strVar/\[*\]/}
I would prefer it over an external call to sed, except there is more to be done, why I use sed anyway:
echo $strVar | sed 's/\[.*\]//'
I don't think there is an elegant solution for grep but might be wrong. In awk I'm not that fluent.

How can I capture all numbers in a string using sed

I tried to use sed to capture numbers in a string with following script:
echo '["770001,德邦优化混合","750005,安信平稳增长混合发起A"]' | sed -n 's/.*"\(\d{6}\),/\1/p'
My expectation is echo
770001
750005
While nothing output. Why?
In case you are ok with awk then following awk may help you in same. Since I have old version of awk so I am using --re-interval if you have newer version of awk then you may not need it.
echo '["770001,德邦优化混合","750005,安信平稳增长混合发起A"]' |
awk --re-interval '{while(match($0,/[0-9]{6}/)){print substr($0,RSTART,RLENGTH);$0=substr($0,RSTART+RLENGTH+1)}}'
Output will be as follows.
770001
750005

Reading numbers from a text line in bash shell

I'm trying to write a bash shell script, that opens a certain file CATALOG.dat, containing the following lines, made of both characters and numbers:
event_0133_pk.gz
event_0291_pk.gz
event_0298_pk.gz
event_0356_pk.gz
event_0501_pk.gz
What I wanna do is print the numbers (only the numbers) inside a new file NUMBERS.dat, using something like > ./NUMBERS.dat, to get:
0133
0291
0298
0356
0501
My problem is: how do I extract the numbers from the text lines? Is there something to make the script read just the number as a variable, like event_0%d_pk.gz in C/C++?
A grep solution:
grep -oP '[0-9]+' CATALOG.dat >NUMBERS.dat
A sed solution:
sed 's/[^0-9]//g' CATALOG.dat >NUMBERS.dat
And an awk solution:
awk -F"[^0-9]+" '{print $2}' CATALOG.dat >NUMBERS.dat
There are many ways that you can achieve your result. One way would be to use awk:
awk -F_ '{print $2}' CATALOG.dat > NUMBERS.dat
This sets the field separator to an underscore, then prints the second field which contains the numbers.
Awk
awk 'gsub(/[^[:digit:]]/,"")' infile
Bash
while read line; do echo ${line//[!0-9]}; done < infile
tr
tr -cd '[[:digit:]\n]' <infile
You can use grep command to extract the number part.
grep -oP '(?<=_)\d+(?=_)' CATALOG.dat
gives output as
0133
0291
0298
0356
0501
Or
much simply
grep -oP '\d+' CATALOG.dat
You don't need perl mode in grep for this. BREs can do this.
grep -o '[[:digit:]]\+' CATALOG.dat > NUMBERS.dat

Resources