How extract a substring from string using bash commands - linux

i want to extract the substring:
"1.0.119"
From:
"/abc/efg/v/y-1.0.119.u"
How it can be done?
(i get the whole string from a pipe)
Thanks

> echo "/abc/efg/v/y-1.0.119.u" | cut -d'-' -f2 | cut -d'.' -f1-3
1.0.119
cut -d'-' -f2 returns what is after the first -.
cut -d'.' -f1-3 returns what is before the third ..

You can match the characters between the last - and the last . with a Bash regex:
$ [[ "/abc/efg/v/y-1.0.119.u" =~ [^-]+-(.*)\. ]] && echo "${BASH_REMATCH[1]}"
1.0.119
Or sed with the same pattern:
$ echo "/abc/efg/v/y-1.0.119.u" | sed 's/^\([^-]*-\)\(.*\)\(\..*$\)/\2/'
1.0.119

echo "/abc/efg/v/y-1.0.119.u" | sed 's/\(^.*-\)\(.*\)\(\..*$\)/\2/'
Use sed to split the text into three sections, separated with brackets and print just the second section.

Related

How to search and delete a pattern from a line?

I need to write a simple bash script that takes a text line
some-pattern something-else
and erases some-pattern and returns only something-else. I wrote a script to do the opposite with grep -o, but I don't know how I could do with this case. Any help is very much appreciated.
sample input:
"SNMPv2::sysLocation.0 = STRING: someLocation"
Desired Output:
"someLocation"
Considering " are NOT in your sample Input_file and expected output, could you please try following with GNU grep.
grep -oP '.*STRING: \K(.*)' Input_file
someLocation
For \K explanation:
\K is a PCRE extension to regex syntax discarding content prior to
that point from being included in match output
You can use sed to delete the part in front of what you want to keep.
Given:
$ echo "$s"
"SNMPv2::sysLocation.0 = STRING: someLocation"
You can do:
$ echo "$s" | sed -nE 's/^.*(someLocation)/\1/p'
someLocation
And if you want to add quotes:
$ echo "$s" | sed -nE 's/^.*(someLocation)/"\1"/p'
"someLocation"
If the portion after STRING: is variable, not fixed, you can use STRING: and the capture anchor:
$ echo "$s" | sed -nE 's/^.*STRING:[[:space:]]*(.*)/"\1"/p'
"someLocation"
Or, sed to capture and print the last word after the last space:
$ echo "$s" | sed -nE 's/([^[:space:]]*$)/\1/p'
You can also use awk if the last word is space separated from the other fields:
$ echo "$s" | awk '{print $NF}'
Or a pipeline with cut and rev works too:
$ echo "$s" | rev | cut -d' ' -f 1 | rev
You can use: echo ${STRING} | awk -F" " '/someLocation/ { print $NF }'
-F will use space (represented by double-quotes with space between them) as separator; /someLocation/ will search for your location; { print $NF } will show the last part of your string (which, I believe, is the place where location is.

How to extract the value before the last underscore in shell script

I need to extract the value before the last underscore in shell script.
Example:
Input: first_second_third_mmddyyy.csv
Output: first_second_third
Input: first_second_mmddyy.csv
Output: first_second
You can use this sed:
sed 's/_[^_]*$//g' file
Test:
$ echo "first_second_third_mmddyyy.csv" | sed 's/_[^_]*$//g'
first_second_third
$ echo "first_second_mmddyy.csv" | sed 's/_[^_]*$//g'
first_second
You can just use shell parameter expansion:
while read -r line; do echo "${line%_*}"; done < file
# ...........................^^^^^^^^^^
You can also use awk or cut as below;
awk -F '_' 'NF{NF-=1};1' file
echo "first_second_third_mmddyyy.csv" | rev | cut -d '_' -f2- | rev
Eg;
$ echo "first_second_third_mmddyyy.csv" | awk -F '_' 'NF{NF-=1};1'
first second third
NF is a variable containing the number of fields in a line.
NF-=1 is subtracting one from the NF variable, to remove last field

How to extract a part of string?

I have string contains a path
string="toto.titi.1.tata.2.abc.def"
I want to extract the substring which is situated after toto.titi.1.tata.2.. but 1 and 2 here are examples and could be other numbers.
In general: I want to extract the substring which situated after toto.titi.[i].tata.[j]..
[i] and [j] are a numbers
How to do it?
Pure bash solution:
[[ $string =~ toto\.titi\.[0-9]+\.tata\.[0-9]+\.(.*$) ]] && result="${BASH_REMATCH[1]}"
echo "$result"
An alternate bash solution that uses parameter expansion instead of a regular expression:
echo "${string#toto.titi.[0-9].tata.[0-9].}"
If the numbers can be multi-digit values (i.e., greater than 9), you would need to use an extended pattern:
shopt -s extglob
echo "${string#toto.titi.+([0-9]).tata.+([0-9]).}"
You can use cut
echo $string | cut -f6- -d'.'
This does it:
echo ${string} | sed -re 's/^toto\.titi\.[[:digit:]]+\.tata\.[[:digit:]]+\.//'
May be like this:
echo "$string" | cut -d '.' -f 6-
You can use sed. Like this:
string="toto.titi.1.tata.2.abc.def"
string=$(sed 's/toto\.titi\.[0-9]\.tata\.[0-9]\.//' <<< "$string")
echo "$string"
Output:
abc.def
try this awk line:
awk -F'toto\\.titi\\.[0-9]+\\.tata\\.[0-9]+\\.' '{print $2}' file
with your example:
kent$ echo "toto.titi.1.tata.2.abc.def"|awk -F'toto\\.titi\\.[0-9]+\\.tata\\.[0-9]+\\.' '{print $2}'
abc.def

Select first part of string

How do I pull a substring from a string. For example, from the string:
'/home/auto/gift/surprise'
take only:
'/home/auto/'
Note that '/home/auto/gift/surprise' may vary, i.e., instead of having 4 directory levels, it may go to 6 or 8, yet I'm only interested in the first 2 folders.
Here's what I've tried so far, without success:
$ pwd
'/home/auto/gift/surprise'
$ pwd | sed 's,^\(.*/\)\?\([^/]*\),\1,'
'/home/auto/gift/'
I think it is better to use cut for this:
$ echo "/home/auto/gift/surpris" | cut -d/ -f1-3
/home/auto
$ echo "/home/auto/gift/surpris/bla/bla" | cut -d/ -f1-3
/home/auto
Note that cut -d/ -f1-3 means: strip the string based on the delimiter /, then print from the 1st to the 3rd parts.
Or also awk:
$ echo "/home/auto/gift/surpris" | awk -F/ 'OFS="/" {print $1,$2,$3}'
/home/auto
$ echo "/home/auto/gift/surpris/bla/bla" | awk -F/ 'OFS="/" {print $1,$2,$3}'
/home/auto
You may use parameter substitution, which is POSIX defined:
$ s="/home/auto/gift/surprise"
$ echo ${s%/*/*}
/home/auto

Need to grab data inbetween tilde character

Can any one advise how to search on linux for some data between a tilde character. I need to get IP data however its been formed like the below.
Details:
20110906000418~118.221.246.17~DATA~DATA~DATA
One more:
echo '20110906000418~118.221.246.17~DATA~DATA~DATA' | sed -r 's/[^~]*~([^~]+)~.*/\1/'
echo "20110906000418~118.221.246.17~DATA~DATA~DATA" | cut -d'~' -f2
This uses the cut command with the delimiter set to ~. The -f2 switch then outputs just the 2nd field.
If the text you give is in a file (called filename), try:
grep "[0-9]*~" filename | cut -d'~' -f2
With cut:
echo "20110906000418~118.221.246.17~DATA~DATA~DATA" | cut -d~ -f2
With awk:
echo "20110906000418~118.221.246.17~DATA~DATA~DATA"
| awk -F~ '{ print $2 }'
In awk:
echo '20110906000418~118.221.246.17~DATA~DATA~DATA' | awk -F~ '{print $2}'
Just use bash
$ string="20110906000418~118.221.246.17~DATA~DATA~DATA"
$ echo ${string#*~}
118.221.246.17~DATA~DATA~DATA
$ string=${string#*~}
$ echo ${string%%~*}
118.221.246.17
one more, using perl:
$ perl -F~ -lane 'print $F[1]' <<< '20110906000418~118.221.246.17~DATA~DATA~DATA'
118.221.246.17
bash:
#!/bin/bash
IFS='~'
while read -a array;
do
echo ${array[1]}
done < ip
If string is constant, the following parameter expansion performs substring extraction:
$ a=20110906000418~118.221.246.17~DATA~DATA~DATA
$ echo ${a:15:14}
118.221.246.17
or using regular expressions in bash:
$ echo $(expr "$a" : '[^~]*~\([^~]*\)~.*')
118.221.246.17
last one, again using pure bash methods:
$ tmp=${a#*~}
$ echo $tmp
118.221.246.17~DATA~DATA~DATA
$ echo ${tmp%%~*}
118.221.246.17

Resources