How to match "whitespace" and "OR" condition with bash script? - linux

I want to match a condition in bash containing "whitespaces" and "OR" condition within strings. I am unable to do as i am new to shell scripting, please help as it going to else loop where it is matching ${myarrlin[1]} . I am getting "Centrify is disabled" but i want the condition to be true here. Here is my code :
FILE_CENT="/etc/nsswitch.conf"
OS=`uname`
if [[ $OS = 'Linux' ]]; then
if [[ -e $FILE_CENT ]]; then
echo "nsswitch.conf found, Proceeding further..."
while read -r LINE
do
if [[ $LINE =~ ^passwd ]]; then
myarrlin=($LINE)
if [[ ${myarrlin[1]} =~ ^(centrify)|(centrifydc)[[:space:]]* || ${myarrlin[1]} =~ [[:space:]]+(centrify)|(centrifydc)[[:space:]]* ]]; then
echo "Centrify is enabled"
else
echo "Centrify is disabled"
fi
fi
done < $FILE_CENT
else
echo "nsswitch.conf does not exist in $OS, cannot fetch CENTRIFY information!"
fi
fi
nsswitch.conf >>>
passwd: centrify files
or
passwd: centrifydc files
or
passwd: files centrify
or
passwd: files centrifydc

Why are you doing this: myarrlin=($LINE) ?
If you just want to know if the line contains centrify:
while read -r LINE
do
if [[ ${LINE} =~ ^passwd ]]; then
if [[ ${LINE} == *"centrify"* ]]; then
echo "Centrify is enabled"
else
echo "Centrify is disabled"
fi
fi
done < $FILE_CENT

Related

getting syntax error: unexpected end of file in bash script

This is my code:
#!/bin/bash
if [[ -z $1 ]]; then
echo "No arguments passed: valid usage is script.sh filename"
else if [[ ! -f "$1" ]]; then
echo "file does not exists"
else
for i in {558..2005};
do
if [[ ! -d "/abc" ]]; then
mkdir /abc
fi
mkdir /abc/xyz$i
cp $1 /abc/xyz$i/$1
done
fi
my error: can anyone please help me i do not know what to do? I do not know where I am making mistake?
./script.sh: line 17: syntax error: unexpected end of file
Use elif instead of else if.
Syntax of if in bash:
if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
Instead of a single if statement with an elif clause, you nested a second if statement in the else clause of the first, but only terminated the second one. Your code, reformatted to highlight the issue, is
if [[ -z $1 ]]; then
echo "No arguments passed: valid usage is script.sh filename"
else
if [[ ! -f "$1" ]]; then
echo "file does not exists"
else
for i in {558..2005};
do
if [[ ! -d "/abc" ]]; then
mkdir /abc
fi
mkdir /abc/xyz$i
cp $1 /abc/xyz$i/$1
done
fi
Notice the lack of a second fi which would terminate the outer if statement.
Using elif, your code becomes
if [[ -z $1 ]]; then
echo "No arguments passed: valid usage is script.sh filename"
elif [[ ! -f "$1" ]]; then
echo "file does not exists"
else
for i in {558..2005};
do
if [[ ! -d "/abc" ]]; then
mkdir /abc
fi
mkdir /abc/xyz$i
cp $1 /abc/xyz$i/$1
done
fi
The elif clause doesn't require a closing fi; it is implicitly terminated by the following else clause.

Shell script if condition not evaluated for a help info display for the user

I had written a help menu for reference about the usage of a shell script my_script.sh
echo $'\n\n'
echo $(printf '=%.0s' {1..100})
printf ' %.0s' {1..40}
echo "Welcome"
echo $(printf '=%.0s' {1..100})
echo $'\n'
arg=$1
echo "Input : $arg"
echo
if [[ arg -eq "-h" ]] || [[ arg -eq "-H" ]] || [[ arg -eq "-help" ]] || [[ arg -eq "-Help" ]] || [[ arg -eq "--h" ]] || [[ arg -eq "--H" ]] || [[ arg -eq "--help" ]] || [[ arg -eq "--Help" ]]; then
echo "Help menu requested...."
echo $'\n\n'
echo $(printf '~%.0s' {1..100})
printf ' %.0s' {1..43}
echo "Help Menu"
echo $(printf '~%.0s' {1..100})
echo $'\n'
exit 0
else
echo "Executing a program...."
./another_script.sh
fi
When I execute `myscript.sh -h' (or any of the '-' prefixed option), it goes to the if condition, but any other argument doesn't. What am I doing wrong here? I'm new to bash scripts.
Two simple problems with your if:
-eq is for integer comparison, = or == for strings
Use $arg in your if (instead of arg).
But: I would recommend using getopts instead of string comparison. This would make the part more robust, taking care of different ordering of parameters, or when one letter parameters are combined into a single argument.
Unfortunately I do not know the exact reason why your code does not work, but I can offer you a quick fix: You can write "==" instead of "-eq" and prefix your variable "arg" with a dollar sign. Then your script should work fine.
Working example (GNU bash 4.4.19):
arg=$1
if [[ $arg == "-h" ]] || [[ $arg == "-H" ]]; then
echo "Help!"
else
echo "Stop!"
fi
the -eq operation is only used for comparing numbers.
To compare strings uses the operation =
You forgot $ sign for variables arg in Bash, should be $arg
When we use variables in Bash, we should better use double quote.
use #() for multiple strings comparison.
so the if conditions [[ arg -eq "-h" ]] should be [[ "$arg" = "-h" ]]
When comparing a variable with multiple strings, we can use [[ "$arg" = #(-h|-H|--help|--HELP|--h|--H|-help|--HELP) ]].
if [[ "$arg" = #(-h|-H|--help|--HELP|--h|--H|-help|--HELP) ]]; then
echo "Help menu requested...."
echo $'\n\n'
echo $(printf '~%.0s' {1..100})
printf ' %.0s' {1..43}
echo "Help Menu"
echo $(printf '~%.0s' {1..100})
echo $'\n'
exit 0
else
echo "Executing a program...."
./another_script.sh
fi
In addition, we can use boxes(boxes - Command line ASCII boxes unlimited!
) to generate a comment box
cat <<EOF | boxes -a c -d shell -p a5 -s 30x9
HELP MENU
bla bla
EOF
output:
########################################
# #
# #
# HELP MENU #
# #
# bla bla #
# #
# #
########################################

until loop with if statements

I am stuck on a part and i don't understand why, let me paste my code:
local correctId=false
echo $ticketMessage
read deviceId
until [[ $deviceId =~ [0-9]+ && correctId = true ]]; do
if [ ! -e $baseDevicesPath"/$deviceId" ]; then
echo $deviceError
correctId=false
else
correctId=true
fi
if [[ ! $deviceId =~ [0-9]+ ]]; then
echo $ticketMessage
fi
read deviceId
done
echo "I DONT COME HERE?"
if both deviceId and correctId are true, it should exit the until loop and go further? but it doesn't, any idea what i do wrong here?
You just have a simple typo. you are missing the $ in front of correctID in your condition:
local correctId=false
echo $ticketMessage
read deviceId
until [[ $deviceId =~ [0-9]+ && $correctId = true ]]; do
if [ ! -e $baseDevicesPath"/$deviceId" ]; then
echo $deviceError
correctId=false
else
correctId=true
fi
if [[ ! $deviceId =~ [0-9]+ ]]; then
echo $ticketMessage
fi
read deviceId
done
echo "NOW YOU WILL END HERE"
Change correctId into $correctId (of ${correctId}).
I would add double quotes:
local correctId="false"
echo ${ticketMessage}
read deviceId
until [[ $deviceId =~ [0-9]+ && "${correctId}" = "true" ]]; do
if [ ! -e "${baseDevicesPath}/${deviceId}" ]; then
echo ${deviceError}
correctId="false"
else
correctId="true"
fi
if [[ ! "${deviceId}" =~ [0-9]+ ]]; then
echo ${ticketMessage}
fi
read deviceId
done
echo "Do you come here?"
here is a bit more readable solution
function findDevice {
echo $ticketMessage;
read deviceId;
while true; do
local errorMessage;
if [[ $deviceId =~ [0-9]+ ]]; then
if [ -e $baseDevicesPath"/$deviceId" ]; then
#valid input, breaking the loop
break;
fi
errorMessage=$deviceError;
else
errorMessage=$ticketMessage;
fi
echo $errorMessage;
read deviceId;
done
}

Shell-Script:Create File List Based on Certain Charachter

I need to create one file list for below files:
APPLE_001
APPLE_002
BBB_004
APPLE_003
I need to create file_list only for
APPLE_001
APPLE_002
APPLE_003
Thanks,
Ipsita
Your specifications are not that narrow, but here a bash script that match your request :
#!/bin/bash
if [[ $# < 2 ]]
then
echo "[ERROR] this script expects two arguments, input file and output file" >&2
exit 1
fi
input_file=$1
output_file=$2
if [[ ! -f $input_file ]]
then
echo "[ERROR] your input file '$input_file' is missing" >&2
exit 1
fi
if [[ -f $output_file ]]
then
echo "[ERROR] your output file '$ouput_file' already exists please move it away" >&2
exit 1
fi
while read LINE
do
if [[ $LINE =~ APPLE_[0-9]+ ]]
then
echo $LINE >> $output_file
else
echo "'$LINE' does not match expected pattern, skip it"
fi
done < $input_file
if [[ -f $ouput_file ]]
then
echo "'$output_file' generated."
else
echo "[WARNING] no pattern found in '$input_file' no file generated"
fi
make it executable ( chmod +x ./list_starting_with.sh )
run it with ./list_starting_with.sh file_in.txt file_out.txt

how to use if to see whether file has suffix in shell bash script [duplicate]

This question already has answers here:
How to check if a string contains a substring in Bash
(29 answers)
Closed 9 years ago.
if[ xxx ]
how to expresss the string or file include '.'
I am new to study shell,thanks for any help
You can use the matching operator:
$ if [[ "abc.def" =~ \. ]]; then echo "yes"; else echo "no"; fi
yes
$ if [[ "abcdef" =~ \. ]]; then echo "yes"; else echo "no"; fi
no
This matches if the dot is the first or last (or only) character in the string. If you expect characters on both sides of the dot, you can do the following:
$ if [[ "ab.cdef" =~ .\.. ]]; then echo "yes"; else echo "no"; fi
yes
$ if [[ ".abcdef" =~ .\.. ]]; then echo "yes"; else echo "no"; fi
no
$ if [[ "abcdef." =~ .\.. ]]; then echo "yes"; else echo "no"; fi
no
You can also use pattern matching:
$ if [[ "ab.cdef" == *?.?* ]]; then echo "yes"; else echo "no"; fi
yes
$ if [[ ".abcdef" == *?.?* ]]; then echo "yes"; else echo "no"; fi
no
$ if [[ "abcdef." == *?.?* ]]; then echo "yes"; else echo "no"; fi
no
A good reference for both patterns and regexes is at Greg's Wiki
bash supports glob-style pattern matching:
if [[ "$file" = *?.?* ]]; then
...
fi
Note that this assumes a prefix as well - this also ensures that it will not match the . and .. directories.
If you want to check for a specific extension:
if [[ "$file" = *?.foo ]]; then
...
fi
echo "xxx.yyy" | grep -q '\.'
if [ $? = 0 ] ; then
# do stuff
fi
Or
echo "xxx.yyy" | grep -q '\.' && <one statement here>
#e.g.
echo "xxx.yyy" | grep -q '\.' && echo "got a dot"

Resources