how can I get a some values in strings in bash script - linux

hi I looked the others questions and tried some things but i couldnt manage to solve it.
My string is that
:CONNECTING TO CPL... PROCESS CPL CONNECTED... Enter command: Enter
command:RESP:0,CPrL-E1002:RESPMSG,Invalid session ID.; Enter
command:RESP:0,CPL-E1014:RESPMSG,System internal error; Enter command:
Connection closed by foreign host.
how Can I take RESP:0,CPL-E1014:RESPMSG,System internal error; this line? Also
RESP:0,CPL-E1014:RESPMSG,System internal error; this line wıll change according the request .So I must take only from RESP: to ; for the second line

test=":CONNECTING TO CPL... PROCESS CPL CONNECTED... Enter command: Enter command:RESP:0,CPrL-E1002:RESPMSG,Invalid session ID.; Enter command:RESP:0,CPL-E1014:RESPMSG,System internal error; Enter command:Connection closed by foreign host."
str=echo $test | cut -d";" -f2
echo ${str:15:100}";"
Here I assumed that your response string comes every time after " Enter command:". 100 is for the maximum length of your response string.

Assuming that the string is in a variable named $str, and that there are no other stars * in the string, you could use an awk filter, like this:
awk -F\* 'NF>1{print $2}' <<< "$str"
Here we use the -F option to set the field separator to the star, and if we find a line with more than one elements (one star or more), we print the second field.
output:
$ echo "$str"
:CONNECTING TO CPL... PROCESS CPL CONNECTED... Enter command: Enter
command:*RESP:0,CPrL-E1002:RESPMSG,Invalid session ID.;* Enter
command:AREE:0,CPL-E1014:RESPMSG,System internal error; Enter command:
Connection closed by foreign host.
$
$ awk -F\* 'NF>1{print $2}' <<< "$str"
RESP:0,CPrL-E1002:RESPMSG,Invalid session ID.;

You can use expr and regular expressions, please refer to this answer first. Have a look at this code :
#!/bin/bash
# foo.sh
# Searches the string for a "RESP:#" message, the # sign is a digit.
string='CONNECTING TO CPL... PROCESS CPL CONNECTED... Enter command:RESP:0,CNDB-0,CPL-0,EMA-0:RESPMSG,success; Enter command: Enter command:
RESP:1,CPL-0,EMA-0:RESPMSG,success; Enter command: Connection closed by foreign host'
regex='RESP\:[0-9]\,CPL\-0\,EMA\-0\:RESPMSG\,[a-zA-Z0-9]*\;'
line=`expr "$string" : '.*\(RESP\:[0-9]\,CPL\-0\,EMA\-0\:RESPMSG\,[a-zA-Z0-9]*\;\)'` # Search the string for the desired line.
respCode=${line:5:1} # Extract RESP:# value using substring...
respMessage=${line:27}
echo $line
echo 'Received response code : '$respCode
echo 'Received response message : '$respMessage

Try doing this using only grep :
$ grep -oP 'command:\KRESP:.*?System internal error;' test.txt
RESP:0,CPL-E1014:RESPMSG,System internal error;

Related

Why Linux shell script read to array command gives more elements than necessary?

Why following Linux shell command for given input (a-b [c=d.e] <f g>) gives extra element (3:'')?
Command:
echo "a-b [c=d.e] <f g>" | while IFS=" []<>=" read -a arr; do for ((i=0;i<${#arr[#]};i++)) do echo "${i}:'${arr[${i}]}'"; done; done
Expected output:
0:'a-b'
1:'c'
2:'d.e'
3:'f'
4:'g'
Actual output:
0:'a-b'
1:'c'
2:'d.e'
3:''
4:'f'
5:'g'
With your shown samples only(in case you are ok with awk). To get your expected output, you could do this in a single awk itself, please try following once. Simple explanation: would be, creating different field separators as per shown samples/need of OP and then traversing through all fields of current line(s) and printing only those which are required.
echo "a-b [c=d.e] <f g>" |
awk -v s1="\'" -F'[ \\[=\\]><]' '{for(i=1;i<=NF;i++){if($i){print count++":"s1 $i s1}}}'
With shown samples, output will be as follows.
0:a-b
1:c
2:d.e
3:f
4:g

How can i add a string with an integer in bash? [duplicate]

This question already has answers here:
Are shell scripts sensitive to encoding and line endings?
(14 answers)
Closed 2 years ago.
I want to read a random txt which contains some random integers in this form:
2:10
4:4
10:15
22:5
Then i want to find the sum of each column . Firstly , i thought of spliting each line like if every line is a string:
columnA="$(cut -d':' -f1 <<<$line)"
columnB="$(cut -d':' -f2 <<<$line)"
columnAcontains the elements of the first column and columnB the elements of the second one . Then i created a variable sumA=0 and i tried to take the sum of each column like that:
sumA=$((columnA+sumA))
I am getting the result i want but with this message as well
")syntax error: operand expected (error token is "
Same for the second column :
sumB=$((columnB+sumB))
The time i am getting this error and i dont get the result i want:
")syntax error: invalid arithmetic operator (error token is "
This is the code in general :
sumA=0
sumB=0
while IFS= read -r line
do
columnA="$(cut -d':' -f1 <<<$line)"
sumA=$((columnA+sumA))
columnB="$(cut -d':' -f2 <<<$line)"
sumB=$((columnB+sumB))
done < "random.txt"
echo $sumA
echo $sumB
Any thoughts?
It could be simplified just to
awk -F: '{sumA+=$1; sumB+=$2} END {printf "%s\n%s\n", sumA, sumB}' random.txt
From the manual:
$ man awk
...
-F fs
--field-separator fs
Use fs for the input field separator (the value of the FS predefined variable).
...
instead of using "cut" use built in bash references: "${variable}"
ColumnA=0
ColumnB=0
while read l
do
ColumnA=$((${l//:*}+$ColumnA))
ColumnB=$((${l//*:}+$ColumnB))
done < random.txt
echo $ColumnA $ColumnB

Can't input date variable in bash

I have a directory /user/reports under which many files are there, one of them is :
report.active_user.30092018.77325.csv
I need output as number after date i.e. 77325 from above file name.
I created below command to find a value from file name:
ls /user/reports | awk -F. '/report.active_user.30092018/ {print $(NF-1)}'
Now, I want current date to be passed in above command as variable and get result:
ls /user/reports | awk -F. '/report.active_user.$(date +'%d%m%Y')/ {print $(NF-1)}'
But not getting required output.
Tried bash script:
#!/usr/bin/env bash
_date=`date +%d%m%Y`
active=$(ls /user/reports | awk -F. '/report.active_user.${_date}/ {print $(NF-1)}')
echo $active
But still output is blank.
Please help with proper syntax.
As #cyrus said you must use double quotes in your variable assignment because simple quote are use only for string and not for containing variables.
Bas use case
number=10
string='I m sentence with or wihtout var $number'
echo $string
Correct use case
number=10
string_with_number="I m sentence with var $number"
echo $string_with_number
You can use simple quote but not englobe all the string
number=10
string_with_number='I m sentence with var '$number
echo $string_with_number
Don't parse ls
You don't need awk for this: you can manage with the shell's capabilities
for file in report.active_user."$(date "+%d%m%Y")"*; do
tmp=${file%.*} # remove the extension
number=${tmp##*.} # remove the prefix up to and including the last dot
echo "$number"
done
See https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

Expect script output

I am trying to output the size of an ARP table from a FW using an Expect script so it can be graphed. After the below code the output displayed to screen is shown:
/usr/bin/expect -f -<< EOD
spawn ssh test#1.2.3.4
sleep 1
expect {
"*word:" {send "password\r"}
}
sleep 1
expect {
"*>" {send "show arp all | match \"total ARP entries in table\"\r"}
}
sleep 1
expect {
"*>" {send "exit\r"}
}
expect eof
EOD
spawn ssh test#1.2.3.4
FW-Active
Password:
Number of failed attempts since last successful login: 0
test#FW-Active(active)> show arp all | match "total ARP entries in table"
total ARP entries in table : 2861
What I am trying to do is be able to output only the numeric value indicated from the total ARP entries in table. I am assuming I need to some how do a "cut" or "awk" or something to extract only the numbers but I am not having any luck. Any help is greatly appreciated.
You store the output of that whole command in a variable, let's say a.
Something like this will probably work. Since you're using expect, you might want to figure out how to store that output as a variable that way you can manipulate it. I stored the output as $a in my example.
$ echo $a
total ARP entries in table : 2861
$ echo ${a% *}
total ARP entries in table :
$ echo ${a% *}-
total ARP entries in table : -
$ echo ${a##* }
2861
Logic explanation (Parameter/Variable Substituion in BASH):
1) To removing/stripping the left hand side part, use # for reaching the first matching character value (reading / parsing from left side), ## for reaching the last matching character/value. It works by giving *<value> within the { } braces.
2) To removing/stripping the right hand side part, use % for reaching the first matching character value (reading / parsing from right side), %% for reaching the last matching character/value. It works by giving <value>* within the { } braces.
Or if you don't want to store the output or anything, then simply do this:
show arp all | match "total ARP entries in table" | grep -o "[0-9][0-9]*"
Or (the following assumes that you don't change
show arp all | match "total ARP entries in table" | sed "s/ *//g"|cut -d':' -f2

Extract Digits From String After Capturing It From File

I'm trying to retrieve a memory value from file, and compare it to reference value. But one thing at a time....
I've attempted using set/source/grep/substring to variable but non of them actually worked. Then I found a way to do it using a for loop (see code).
The issue: I'm receiving the entire string from the file, but I can't manage to get rid of the last character in it.
#!/bin/bash
#source start_params.properties
#mem_val= "$default.default.minmaxmemory.main"
#mem_val= grep "default.default.minmaxmemory.main" start_params.properties
for mLine in $(grep 'default.default.minmaxmemory.main' start_params.properties)
do
echo "$mLine"
done
echo "${mLine:4:5}" # didn't get rid of the last `m` in `-max4095m`
v1="max"
v2="m"
echo "$mLine" | sed -e "s/.*${v1}//;s/${v2}.*//" #this echo the right value.
The loop iterates twice:
First output: default.default.minmaxmemory.main=-min512m
Second output: -max4096m
Then the sed command output is 4096,but how can I change the last line in the code S.T. it'll store the value in a variable?
Thank you for your suggestions,
You could use grep to filter the max part and then another a grep -o to extract the numbers:
echo "$mLine" | grep "$max" | grep -o '[[:digit:]]*'
$ sed '/max[0-9]/!d; s/.*max//; s/m//' start_params.properties
4096
remove lines not matching max[0-9]
remove first part of line until max
remove final m

Resources