Split String in Unix Shell Script - shell

I have a String like this
//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf
and want to get last part of
00000000957481f9-08d035805a5c94bf

Let's say you have
text="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
If you know the position, i.e. in this case the 9th, you can go with
echo "$text" | cut -d'/' -f9
However, if this is dynamic and your want to split at "/", it's safer to go with:
echo "${text##*/}"
This removes everything from the beginning to the last occurrence of "/" and should be the shortest form to do it.
For more information on this see: Bash Reference manual
For more information on cut see: cut man page

The tool basename does exactly that:
$ basename //ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf
00000000957481f9-08d035805a5c94bf

I would use bash string function:
$ string="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
$ echo "${string##*/}"
00000000957481f9-08d035805a5c94bf
But following are some other options:
$ awk -F'/' '$0=$NF' <<< "$string"
00000000957481f9-08d035805a5c94bf
$ sed 's#.*/##g' <<< "$string"
00000000957481f9-08d035805a5c94bf
Note: <<< is herestring notation. They do not create a subshell, however, they are NOT portable to POSIX sh (as implemented by shells such as ash or dash).

In case you want more than just the last part of the path,
you could do something like this:
echo $PWD | rev | cut -d'/' -f1-2 | rev

You can use this BASH regex:
s='//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf'
[[ "$s" =~ [^/]+$ ]] && echo "${BASH_REMATCH[0]}"
00000000957481f9-08d035805a5c94bf

This can be done easily in awk:
string="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
echo "${string}" | awk -v FS="/" '{ print $NF }'
Use "/" as field separator and print the last field.

You can try this...
echo //ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf |awk -F "/" '{print $NF}'

Related

Get only numbers in output

I need to get only numbers from this:
release/M_0.1.0
thus, need to extract with bash to have in output this:
0.1.0.
I have tried this but cannot finish it:
echo "release/M_0.1.0" | awk -F'/' '{print $2}'
And what about if given such string? relea234se/sdf23_4Mm0.1.0.8. How to get only 0.1.0.8? Please pay attention that this can be random digits such as 0.2 or 1.9.1.
Please check if this grep command works
echo "release/M_0.1.0" | egrep -o '[0-9.]+'
You could also use general parameter expansion parsing to literally remove characters up through the last that isn't digits or dots.
$: ver() { echo "${1//*[^.0-9]/}"; }
$: ver release/M_0.1.0
0.1.0
$: ver relea234se/sdf23_4Mm0.1.0.8
0.1.0.8
With sed you can do:
echo "release/M_0.1.0" | sed 's#.*_##'
Output:
0.1.0
Considering that your Input_file will be same as shown samples.
echo "$var" | awk -F'_' '{print $2}'
OR could use sub:
echo "$var" | awk '{sub(/.*_/,"")} 1'
With simple bash you could use:
echo "${var#*_}"
echo release/M_0.1.0 | awk -F\_ '{print $2}'
0.1.0
Take your pick:
$ var='relea234se/sdf23_4Mm0.1.0.8'
$ [[ $var =~ .*[^0-9.](.*) ]] && echo "${BASH_REMATCH[1]}"
0.1.0.8
$ echo "$var" | sed 's/.*[^0-9.]//'
0.1.0.8
$ echo "$var" | awk -F'[^0-9.]' '{print $NF}'
0.1.0.8
if data in d file, tried on gnu sed:
sed -E 's/relea.*/.*([0-9][0-9.]*)$/\1/' d

"awk" and "cut" behaving differently in bash script

I'm trying to cut the below string starting on the single quote:
name1=O'Reilly
so it leaves:
name2=Reilly
That's easy from the command line with the following commands:
echo $name | cut -d\' -f
echo $name | awk -F\' '{print $2}'
However when I run these commands from a script the string remains unaltered. I've been looking into problems with using single quotes as a delimiter but couldn't find anything. Any way to solve this issue?
That does not change the string the variable expands to, it just outputs the result of string manipulation.
If you want to create a new reference for variable name, use command substitution to save the result of cut/awk operation as variable name:
% name="O'Reilly"
% echo "$name" | awk -F\' '{print $2}'
Reilly
% name=$(echo "$name" | awk -F\' '{print $2}')
% echo "$name"
Reilly
On the other hand, if you want to declare the input as one (name1), and save the output as a different variable (name2):
% name1="O'Reilly"
% name2=$(echo "$name1" | awk -F\' '{print $2}')
% echo "$name2"
Reilly
This might be easier to get using Parameter expansion though:
$ name="O'Reilly"
$ echo "${name#*\'}"
Reilly
$ name="${name#*\'}"
$ echo "$name"
Reilly

Extract part between two strings in a variable in Unix

I have a string,
tester_one="update set_tables set abc=7 where bcd=9"
Here I wish to extract only the part between "set" and "where",
abc=7
I tried a couple of Unix commands, but it picked up any occurrences of set or where encountered, before the part where I want it to pick up.
I have an idea on how to do it Java but I am lost in Unix as I am new to this.
Using sed
$ echo "$tester_one" | sed -E 's/.*set (.*) where.*/\1/'
abc=7
To capture it in a variable:
$ new=$(echo "$tester_one" | sed -E 's/.*set (.*) where.*/\1/')
$ echo $new
abc=7
Using awk
$ echo "$tester_one" | awk '{sub(/.*set /,""); sub(/ where.*/,""); print;}'
abc=7
Using grep -P
If your grep supports the -P (perl-like) option:
$ echo "$tester_one" | grep -oP '(?<=set ).*(?= where)'
abc=7
You can get it out with sed. Something like:
echo "$tester_one" | sed 's/.* set \(.*\) where .*/\1/'
Using Bash Pattern Matching:
#!/bin/bash
tester_one="update set_tables set abc=7 where bcd=9"
pat=".* set (.*) where"
[[ $tester_one =~ $pat ]]
echo "${BASH_REMATCH[1]}"
You can also use set and where as field separators and print the field that lies in between them:
$ awk -F"set | where" '{print $2}' <<< "update set_tables set abc=7 where bcd=9"
abc=7
As with your other question, this can be achieved in pure bash, without the use of external tools like sed/awk/grep.
#!/usr/bin/env bash
tester_one="update set_tables set abc=7 where bcd=9"
output="${tester_one#* set }"
output="${output% where }"
echo "$output"
Note the spaces around "set" and "where" in the parameter expansion lines. As you might expect, you'll need to be careful with this if the $tester_one variable contains the distinct "set" or "where" in places that you don't expect them.
That said, I like Jahid's answer better. :-)

Capitalize bash variable

I have the following line in bash:
echo "Manufacturer: $(echo ${family:-$name}|cut -d' ' -f1)"
I would like to capitalize the echoed string using the ${var^} syntax but not sure how to add this to the current line. Can someone please suggest how to do this?
two one liners
$ echo "watever" | awk '{print toupper($0)}'
$ echo "watever" | tr '[:lower:]' '[:upper:]'
Just store above command's output in a variable using command substitution:
s=$(echo "Manufacturer: $(echo ${family:-$name}|cut -d' ' -f1)")
and then use:
echo "${s^^}"
to capitalize the string.
sed is handy here:
name=smith
family=""
echo "Manufacturer: $(sed 's/[^[:blank:]]\+/\U&/' <<< "${family:-$name}")"
Manufacturer: SMITH
If you only want to "title-case" it ("Manufacturer: Smith"), use \u instead of \U

get a part of string just like accessing an array?

In shell,
s="abc\tdef\tghi" # 3 words separated by \t
What if I want to get the second word which is def?
PS
I know cut can do the job, but any way else just like variable substitution?
How about cut ?
[cnicutar#ariel ~]$ echo -e $s | cut -f2
def
Or maybe awk:
echo -e $s | awk '{print $2}'
Maybe you're looking for this.
s="abc\tdef\tghi"
s=${s#*\t}
s=${s%\\t*}
echo $s

Resources