Extracting UUID string from a text using shell script commands - shell

I have a text line as:
host_id -------------------------------------- f5f4d3e7-fdc4-49f2-b32c-13280bc7db66 (1 rows)
And I want to extract only the UUID value within the text using shell script as I need to run this on ubuntu to execute some other commands using the value. I tried using cut command:
cut -d '-' -f2 | cut -d '(' -f1
But couldn't succeed to specify the cut character for before and after of the UUID string.

The problem using cut -d'-' in your case is that the field (-f) values you will have to add is not 2 but 38 and above (that's the number of consecutive - symbols in your string), because of how cut works. This is the output you will get if you just set the field 39 (using cut -d'-' -f39):
f5f4d3e7
But also the UUID string you want contains additional hyphens, so if you still want to get it that way (using cut) you will have to expand your field selection, in this case by adding -f39-43. But that just will not solve the problem of showing the string "(1 rows)" after it, so by running cut -d'-' -f39-43 you will get this:
f5f4d3e7-fdc4-49f2-b32c-13280bc7db66 (1 rows)
And that's why you used a second cut filter to just pick the UUID value string. While this is okay, it seems to be pretty much handy using awk, which will solve all these problems in one single command:
cat file.txt | awk '{ print $3 }'
Or if your string is not coming from a file:
echo "host_id -------------------------------------- f5f4d3e7-fdc4-49f2-b32c-13280bc7db66 (1 rows)" | awk '{ print $3 }'

Related

How do I seperate a link to get the end of a URL in shell?

I have some data that looks like this
"thumbnailUrl": "http://placehold.it/150/adf4e1"
I want to know how I can get the trailing part of the URL, I want the output to be
adf4e1
I was trying to grep when starting with / and ending with " but I'm only a beginner in shell scripting and need some help.
I came up with a quick and dirty solution, using grep (with perl regex) and cut:
$ cat file
"thumbnailUrl": "http://placehold.it/150/adf4e1"
"anotherUrl": "http://stackoverflow.com/questions/3979680"
"thumbnailUrl": "http://facebook.com/12f"
"randortag": "http://google.com/this/is/how/we/roll/3fk19as1"
$ cat file | grep -o '/\w*"$' | cut -d'/' -f2- | cut -d'"' -f1
adf4e1
3979680
12f
3fk19as1
We could kill this with a thousand little cuts, or just one blow from Awk:
awk -F'[/"]' '{ print $(NF-1); }'
Test:
$ echo '"thumbnailUrl": "http://placehold.it/150/adf4e1"' \
| awk -F'[/"]' '{ print $(NF-1); }'
adf4e1
Filter thorugh Awk using double quotes and slashes as field separators. This means that the trailing part ../adf4e1" is separated as {..}</>{adf4e1}<">{} where curly braces denote fields and angle brackets separators. The Awk variable NF gives the 1-based number of fields and so $NF is the last field. That's not the one we want, because it is blank; we want $(NF-1): the second last field.
"Golfed" version:
awk -F[/\"] '$0=$(NF-1)'
If the original string is coming from a larger JSON object, use something like jq to extract the value you want.
For example:
$ jq -n '{thumbnail: "http://placehold.it/150/adf4e1"}' |
> jq -r '.thumbnail|split("/")[-1]'
adf4e1
(The first command just generates a valid JSON object representing the original source of your data; the second command parses it and extracts the desired value. The split function splits the URL into an array, from which you only care about the last element.)
You can also do this purely in bash using string replacement and substring removal if you wrap your string in single quotes and assign it to a variable.
#!/bin/bash
string='"thumbnailUrl": "http://placehold.it/150/adf4e1"'
string="${string//\"}"
echo "${string##*/}"
adf4e1 #output
You can do that using 'cut' command in linux. Cut it using '/' and keep the last cut. Try it, its fun!
Refer http://www.thegeekstuff.com/2013/06/cut-command-examples

Shell cut delimiter before last

I`m trying to cut a string (Name of a file) where I have to get a variable in the name.
But the problem is, I have to put it in a shell variable, until now it is ok.
Here is the example of what i have to do.
NAME_OF_THE_FILE_VARIABLEiWANTtoGET_DATE
NAMEfile_VARIABLEiWANT_DATE
NAME_FILE_VARIABLEiWANT_DATE
The position of the variable I want always can change, but it will be always 1 before last. The delimiter is the "_".
Is there a way to count the size of the array to get size-1 or something like that?
OBS: when i cut strings I always use things like that:
VARIABLEiWANT=`echo "$FILENAME" | cut 1 -d "_"`
awk -F'_' '{print $(NF-1)}' file
or you have a string
awk -F'_' '{print $(NF-1)}' <<< "$FILENAME"
save the output of above oneliner into your variable.
IFS=_ read -a array <<< "$FILENAME"
variable_i_want=${array[${#array[#]}-2]}
It's a bit of a mess visually, but it's more efficient than starting a new process. ${#array[#]} is the number of elements read from FILENAME, so the indices for the array range from 0 to ${#array[#]}-1.
As of bash 4.3, though, you can use a negative index instead of computing it.
variable_i_want=${array[-2]}
If you need POSIX compatibility (no arrays), then
tmp=${FILENAME%_${FILENAME##*_}} # FILENAME with last field removed
variable_i_want=${tmp##*_} # last field of tmp
Just got it... I find someone using a cat function... I got to use it with the echo... and rev. didn't understand the rev thing, but I think it revert the order of the delimiter.
CODIGO=`echo "$ARQ_NAME" | rev | cut -d "_" -f 2 | rev `

Getting a user's log-in date from who command

I've been trying to get only the date a user logged in in bash.
I tried using
who | grep 'user'
which gives me the data for the user just fine. I've been unsuccessful at getting a string containing the date the user logged in, however:
who | grep 'user' | cut -f3
doesn't work for some reason.
I tried to use a space as a delimiter, but which field to cut would vary depending on the length of the username:
who | grep 'user' | cut -d ' ' -f12
would give me the date for usernames of a fixed length, but would give me a different field for usernames of different lengths.
It looks like the delimiter is a tab as the number of spaces between the first and second fields changes depending on the length of the username. I tried specifying the delimiter as a tab (even though cut assumes it is), but that didn't work either.
Try using awk instead of cut, you can even get awk to do the filtering grep is currently doing:
who | awk '/user/{print $3}'
The use of $3 means that the 3rd column of the data will be output. Awk's default field separator is a sequence of whitespaces.
Using awk to replace only your cut command (and not grep) would result in:
who | grep 'user' | awk '{print $3}'
Use awk or some other tool less bothered by multiple delimiters than cut.
who | awk '{print $3}'

shell script to extract text from a variable separated by forward slashes

I am trying to find a way to to extract text from a variable with words separated by a forward slash. I attempted it using cut, so here's an example:
set variable = '/one/two/three/four'
Say I just want to extract three from this, I used:
cut -d/ -f3 <<<"${variable}"
But this seems to not work. Any ideas of what I'm doing wrong? Or is there a way of using AWK to do this?
You need to remove the spaces before and after to = during string or variable assignment. And tell the cut command to print the 4th field.
$ variable='/one/two/three/four'
$ cut -d/ -f4 <<<"${variable}"
three
With the delimiter /, cut command splits the input like.
/one/two/three/four
| | | | |
1 2 3 4 5
that is, when it splits on first slash , you get an empty string as first column.
I think that the main problem here is in your assignment. Try this:
var='/one/two/three/four'
cut -d/ -f4 <<<"$var"
Here is an awk version:
awk -F\/ '{print $4}' <<< "$variable"
three
or
echo "$variable" | awk -F\/ '{print $4}'
three
PS to set a variable not need for set and remove spaces around =
variable='/one/two/three/four'

Cut command does not appear to be working

I'm piping a command to cut and nothing appears to be happening.
The output of the command looks like this:
Name File Info OS
11 FileName1 OS1
12 FileName2 OS2
13 FileName3 OS3
I'm trying to extract column 1,2 from all rows (starting with row 2) using the following:
my_command | cut -f1,2 and the output is exactly the same as the original.
Cut doen't behave well with multiple spaces as a delimiter. Use awk instead
mycommand | awk 'NR>1{print $1,$2}'
use tr -s to convert repeating spaces into single space. Now cut can be used where single space is delimiter seperating columns.
mycommand | tr -s ' ' | cut -d' ' -f1,2
If multiple spaces are used for a delimiter and the column positions are fixed, you would use column numbers with cut:
mycommand | cut -c1-27
Or you could lose the front spaces with:
mycommand | cut -c5-27
This will work even if your fields have embedded spaces. The awk method will fail if you have embedded spaces in your fields.

Resources