Compare strings in shell script - bash

I have a file named parameters.txt whose contents are as follows:
sheet_name:TEST
sheet_id:CST
sheet_access:YES
And I have a shell script which fetches this text from the parameters.txt file. It uses : as a delimiter for each line of the parameters.txt file and stores whatever is left of : in var1 and whatever is right of : in var2. I want to print matched when var1 stores sheet_name and not matched when it doesn't stores sheet_name. Following is my code which always prints matched irrespective of what var1 stores:
filename=parameters.txt
IFS=$'\n' # make newlines the only separator
for j in `cat $filename`
do
var1=${j%:*} # stores text before :
var2=${j#*:} # stores text after :
if [ “$var1” == “sheet_name” ]; then
echo ‘matched’
else
echo “not matched“
fi
done
What am I doing wrong? Kindly help.

You have useless use of cat. But how about some [ shell parameter expansion ] ?
while read line
do
if [[ "${line%:*}" = "sheet_name" ]] #double quote variables deals word splitting
then
echo "matched"
fi
done<parameters.txt
would do exactly what you're looking for.
Message for you
[ ShellCheck ] says,
"To read lines rather than words, pipe/redirect to a 'while read'
loop."
Check [ this ] note from shellcheck.

How about this?
filename=parameters.txt
while IFS=: read -r first second; do
if [ “$first” == “sheet_name” ]; then
echo ‘matched’
else
echo “not matched“
fi
done < $filename

Related

Not able to skip blank lines in a shell script

I am reading a text file line by line and taking the count of all lines as a part of my requirement.
When there is blank line then it get messed up. I tried with if condition for [ -z "$line" ] , however not able to succeed.
Here is my current code:
countNumberOfCases() {
echo "2. Counting number of test cases -----------"
cd $SCRIPT_EXECUTION_DIR
FILE_NAME=Features
while read line || [[ -n "$line" ]]
do
TEST_CASE="$line"
if [ "${TEST_CASE:0:1}" != "#" ] ; then
cd $MVN_EXECUTION_DIR
runTestCase
fi
done < $FILE_NAME
echo " v_ToalNoOfCases : = " $v_ToalNoOfCases
}
And below is Features file
web/sprintTwo/TC_002_MultipleLoginScenario.feature
#web/sprintOne/TC_001_SendMoneyTransaction_Spec.feature
web/sprintTwo/TC_003_MultipleLoginScenario.feature
#web/sprintOne/TC_004_SendMoneyTransaction_Spec.feature
When there is blank line it wont work properly so my requirement is that if there is blank line then it should be skipped and should not get considered.
You can write your loop in a little more robust way:
#!/bin/bash
while read -r line || [[ $line ]]; do # read lines one by one
cd "$mvn_execution_dir" # make sure this is an absolute path
# or move it outside the loop unless "runTestCase" function changes the current directory
runTestCase "$line" # need to pass the argument?
done < <(sed -E '/^[[:blank:]]*$/d; /^[[:blank:]]+#/d' "$file_name") # strip blanks and comments
A few things:
get your script checked at shellcheck for common mistakes
see this post for proper variable naming convention:
Correct Bash and shell script variable capitalization
see this discussion about [ vs [[ in Bash
Test for non-zero length string in Bash: [ -n “$var” ] or [ “$var” ]
about reading lines from a text file
Looping through the content of a file in Bash

Creating new shell variables in a loop

Through some here help I was to get only the text between quotation marks in a file like so:
text undefined but text
something something text something
shouldfindthis "dolphin"
butalsothis "elephant"
by doing:
i=0
regex='(".*?")' # Match all what is between "
while read line # read file line by line
do
if [[ $line =~ $regex ]]; then # If regex match
vars[$i]="${BASH_REMATCH[1]}" # store capturing group in a array
i=$((i + 1))
fi
done < txt # file "txt"
# Print what we found
if [ -v "vars" ]; then # if we found something , "vars" will exist
for var in "${vars[#]}"
do
echo "$var"
done
fi
Yielding an output:
$ ./script.sh
"dolphin"
"elephant"
Is there a way to mark these as variables? As such that dolphin is $text1 and elephant is $text2? in doing so that I can replace only the text within the paranthasis?
First: Using arrays, as your code already does, is the best-practice approach. Don't change it. However, if you really want to write to separate variables rather than array, then replace:
vars[$i]="${BASH_REMATCH[1]}" # this could also be vars+=( "${BASH_REMATCH[1]}" )
...with...
printf -v "text$i" '%s' "${BASH_REMATCH[1]}"
If you want to eliminate the quotes themselves, move them outside the grouping operator in your regex:
regex='"([^"]*)"'

nested if statement not working using while read variable

I have a csv file that i am reading with a "while read" statement and i want to run an if statement on one of the fields in the csv.
====================================
csv file
client1,admin,password,5.9
client2,admin,password,5.8
====================================
this is my script
while read clientid user pass version
do
if [ '$version' = "5.9" ];
then
echo "IS"
else
echo "NOT"
fi
done < $1
The problem is that the if statement does not work.
It does not echo IS when the version is 5.9, it just keeps saying NOT, unless i change it to !=
I have tried using single and double quotes, even without... still doesn't work as expected.
The goal is to run commands until the end of the file.
Is this script correct for doing this?
Obviously the IS and NOT would be replaced by actual command, this is just for testing.
The sample csv file provided has trailing whitespace on the line, which can be removed from the version variable using parameter expansion.
This should work:
while IFS=, read -r clientid user pass version; do
if [ "${version//[[:space:]]/}" = "5.9" ]; then
echo "IS"
else
echo "NOT"
fi
done < $1
And here's another:
while IFS=$' \t\r\n' read -r line; do
IFS=, read -r clientid user pass version __ <<< "$line"
if [[ $version == '5.9' ]]; then
echo "IS"
else
echo "NOT"
fi
done < "$1"
Quote variables in the open always to prevent word splitting and pathname expansion.
Prefer [[ ]] over [ ]. It doesn't do word splitting and pathname expansion.
IFS=$' \t\r\n' trims out leading and trailing spaces.
__ is added to store surplus values just in case.
You can add the IFS value comma and whitespace IFS=', ' . You will get the exact result.
#!/bin/bash
IFS=', '
while read clientid user pass version
do
if [ "$version" == "5.9" ] ; then
echo "IS"
else
echo "NOT"
fi
done < $1

Compare $1 with another string in bash

I've spent 2 hours with an if statement, that never works like I want:
#should return true
if [ "$1" == "355258054414904" ]; then
Here is the whole script:
#!/bin/bash
param=$1
INPUT=simu_900_imei_user_pass.csv
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT ime not found"; exit 99; }
while read imei email pass
do
echo "First Parameter-IMEI: $1"
if [ "$1" == "355258054414904" ]; then
echo "GOOD"
fi
done < $INPUT
IFS=$OLDIFS
This is the output of the script:
First Parameter-IMEI: 355258054414904
First Parameter-IMEI: 355258054414904
First Parameter-IMEI: 355258054414904
I have seen a lot of pages about the subject, but I can't make it work :(
EDIT: I Join the content of csv for better understanding ! Tx for your help !
4790057be1803096,user1,pass1
355258054414904,juju,capp
4790057be1803096,user2,pass2
358854053154579,user3,pass3
The reason $1 does not match is because $1 means the first parameter given to the script on the command line, while you want it to match the first field read from the file. That value is in $imei.
You probably meant:
if [ "$imei" == "355258054414904" ]; then
echo "GOOD"
fi
Since it is inside the loop where you read input file line by line.
To check content of $1 use:
cat -vet <<< "$1"
UPDATE: To strip \r from $1 have this at top:
param=$(tr -d '\r' <<< "$1")
And then use "$param" in rest of your script.
To test string equality with [ you want to use a single '=' sign.

Bash: Formatting results inside for loop from a ls command

How come the additional 'Line' insideecho "Line $line" is not prepended to all files inside the for loop?
#!/bin/bash
INPUT=targets.csv
IFS=","
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read target user password path
do
result=$(sshpass -p "$password" ssh -n "$user"#"$target" ls "$path"*file* 2>/dev/null)
if [ $? -ne 0 ]
then
echo "No Heap dumps detected."
else
echo "Found a Heap dump! Possible OOM issue detected"
for line in $result
do
echo "Line $line"
done
fi
done < $INPUT
.csv file contents ..
rob#laptop:~/scripts$ cat targets.csv
server.com,root,passw0rd,/root/
script output ..
rob#laptop:~/scripts$ ./checkForHeapdump.sh
Found a Heap dump! Possible OOM issue detected
Line file1.txt
file2.txt
The statement:
for line in $result
performs word splitting on $result to get each element that $line should be set to. Word splitting uses the delimiters in $IFS. Earlier in the script you set this to just ,. So this loop will iterate over comma-separated data in $result. Since there aren't any commas in it, it's just a single element.
If you want to split it by lines, do:
IFS="
"
for line in $result

Resources