shell scripting: how to cut line in variable - shell

I'm new to shell scripting. I've tried to search online, but I couldn't find what I was looking for - how do I cut a variable to get the value I'm looking for?
for example I have:
Result=`awk -F : -v "Title=" -v "Author=" 'tolower() == tolower(Title) && tolower() == tolower(Author)' BookDB.txt`
//which will return:
//Result= Black:Hat:12.30:20:30
I've tried doing this, but it won't work:
PRICE= cut -d ":" -f 3 $Result
Any help would be appreciated, thanks!

Your code is not wrong ... well, at least most of it!
Doing echo 'Result= Black:Hat:12.30:20:30' | cut -d ":" -f 3 will give the result 12.30.
The issue is that you probably want to use it on a shell script.
To do that just try the following:
PRICE=`cut -d ":" -f 3 $Result`
What I did was basically putting ` before and after the expression that you want to store in your variable.
Reference to learn more: http://www.freeos.com/guides/lsst/ch02sec08.html
Best of luck!

How about using awk...
input="Black:Hat:12.30:20:30"
first=$(echo input | awk -F":" '{print $1}')
echo $first
second=$(echo $input | awk -F":" '{print $2}')
echo $second
date=$(echo $input | awk -F":" '{print $3 ":" $4 ":" $5}')
echo $date
You might have to edit to fit your exact requirements.

Related

Get Year, Month, and Date from Variable

I have a variable of the format $var_YYYY_MM_DD_HH_MM_SS.txt
Eg: variable=sample_data_2017_01_01_10_22_10.txt
I need to extract the following from this variable:
Year=YYYY
Month=MM
Date=DD
Can you please help?
Use the native bash, regex operator ~ and use the captured groups to store them in variables for using it later.
variable="sample_data_2017_01_01_10_22_10.txt"
if [[ $variable =~ ^sample_data_([[:digit:]]{4})_([[:digit:]]{2})_([[:digit:]]{2}).*$ ]]; then
year="${BASH_REMATCH[1]}"
month="${BASH_REMATCH[2]}"
date="${BASH_REMATCH[3]}"
fi
You could try:
Year=$(echo $variable | cut -d '_' -f3)
Month=$(echo $variable | cut -d '_' -f4)
Date=$(echo $variable | cut -d '_' -f5)
This only works if you are sure your variable is laid out in the exact way you describe in your question though. It splits up the string delimited by the '_' character and then returns the field denoted -f argument to cut.
You can simply use read command with setting IFS='_'.
$ variable=sample_data_2017_01_01_10_22_10.txt
$ IFS='_' read -r tmp tmp Year Month Date tmp <<< "$variable"
$ echo "$Year : $Month : $Date"
2017 : 01 : 01
Using awk
Year=$(echo $variable | awk '{split($0,a,"_"); print a[3]}')
Month=$(echo $variable | awk '{split($0,a,"_"); print a[4]}')
Day=$(echo $variable | awk '{split($0,a,"_"); print a[5]}')
Building on some of the other awk solutions a more complete solution would be:
echo $variable | awk -F_ '{ printf "Year="$3"\nMonth="$4"\nDate="$5"\n" }'

Bash Cut text from line with different delimiters

I have a variable with value like:
#capability_ids type="list">[LOADBALANCER]</capability_ids>#
And need to extract from this string type of equipment ( LOADBALANCER ).
I've tried to use cut, but don't know how write cut command with different delimiters.
DeviceType=$( echo $DeviceTypeDirty | cut -d'[' -f1)
Can enywone help me with right solution on bash?
use awk with regular expression: awk -F '[\\[\\]]' '{print $2}'
$ echo '#capability_ids type="list">[L3SWITCH]/capability_ids>#'|awk -F '[\\[\\]]' '{print $2}'
$ L3SWITCH
$ DeviceType=$( echo "$DeviceTypeDirty" | awk -F '[\\[\\]]' '{print $2}')
I tried and got to extract "LOADBALANCER"
Administrators-MacBook-Pro:~$ echo "\"list\">[LOADBALANCER]
</capability_ids>#"|awk -F '[][]' '{print $2}'
LOADBALANCER
Administrators-MacBook-Pro:~$
Hope that helps!
Using cut:
DeviceTypeDirty="#capability_ids type="list">[LOADBALANCER]</capability_ids>#"
DeviceType="$(echo "$DeviceTypeDirty" | cut -d'[' -f2 | cut -d']' -f1)"
Output:
echo "$DeviceType"
LOADBALANCER

Split String in Unix Shell Script

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}'

Length of a specific field, and showing the record in much easier way

My goal is to find out the length of the second field and if the length is more than five characters, then I need to show the entire record using shell scripts/command.
echo "From the csv file"
cat latency.csv |
while read line
do
latency=`echo $line | cut -d"," -f2 | tr -d " "`
length=$(echo ${#latency})
if [ $length -gt 5 ]
then
echo $line
fi
done
There is nothing wrong with my code, but being UNIX/Linux, I thought there should be a simpler way of doing such things.
Is there one such simpler method?
awk -F, 'length($2)>5' file
this should work
updated
awk -F, '{a=$0;gsub(/ /,"",$2);if(length($2)>5)print a}' file
awk -F, '{
t = $2
gsub(/ /, x, t)
if (length(t) > 5)
print
}' latency.csv
Or:
perl -F, -ane'
print if
$F[1] =~ tr/ //dc > 5
' latency.csv

Bash awk one-liner not printing

Expecting this to print out abc - but I get nothing, every time, nothing.
echo abc=xyz | g="$(awk -F "=" '{print $1}')" | echo $g
A pipeline isn't a set of separate assignments. However, you could rewrite your current code as follows:
result=$(
echo 'abc=xyz' | awk -F '=' '{print $1}'
)
echo "$result"
However, a more Bash-centric solution without intermediate assignments could take advantage of a here-string. For example:
awk -F '=' '{print $1}' <<< 'abc=xyz'
Other solutions are possible, too, but this should be enough to get you started in the right direction.

Resources