finding substring in string in shell script not working - shell

I have a test.cfg file whose contents are:
product_identifier=XR656_HD;G6_656
program_family=STR
and a script file as
#!/bin/bash
CONFIG_FILE="test.cfg"
getValueforKeyInProdConfig ()
{
key=$1
if [ -e $CONFIG_FILE ]; then
value=`cat $CONFIG_FILE | grep $key | cut -d "=" -f2 | tr -d '\r'`
echo "$value"
else
echo ""
fi
}
product_identifier="$(getValueforKeyInProdConfig "product_identifier")"
program_family="$(getValueforKeyInProdConfig "program_family")"
echo "product_identifier=$product_identifier"
echo "program_family=$program_family"
if [[ ( $program_family == "STR" ) && ( ($product_identifier == *"G6_656"*) || ($product_identifier == *"G6_646"*) ) ]]; then
echo "found string"
else
echo "unknown"
fi
But the output is:
product_identifier=XR656_HD;G6_656
program_family=STR
unknown
I am expecting the output to be
found string
How should I compare substring in bash to make the script working

Why don't you just source your CONFIG_FILE?
$ cat test.cfg
product_identifier='XR656_HD;G6_656'
program_family=STR
Script
#!/bin/bash
CONFIG_FILE="test.cfg"
. "$CONFIG_FILE"
echo product_identifier=$product_identifier
echo program_family=$program_family
[[ $program_family == "STR" ]] && \
[[ $product_identifier =~ .*G6_6[45]6 ]] && \
echo "found string" || echo "unknown"
Testing
$ ./test
product_identifier=XR656_HD;G6_646
program_family=STR
found string
$ ./test
product_identifier=XR656_HD;G6_656
program_family=STR
found string
$ ./test
product_identifier=XR656_HD;G6_676
program_family=STR
unknown
$ ./test
product_identifier=XR656_HD;G6_656
program_family=fail
unknown

Related

Strange syntax error in if condition - Shell Script

So I'm making a shell script in Ubuntu. It's purpose is simple. You give a command with arguments and you get a different operation each time. The problem is that when I run the the script it won't actually run because of a syntax error in one elif. The most suspicious thing is that I have a similar elif above wich works or at least doesn't pop a syntax error...
I'm leaving my code for you to see it and understand. Thanks in advance!
if [ "$1" = "-a" -a $# -lt 3 ]
then
echo "Add a new line in katalogos!"
read -p "Give me a name... " name
read -p "Give me a surname... " surname
read -p "Give me a city name... " cityName
read -p "Give me a phone number... " num
echo "$name $surname $cityName $num" > katalogos
elif [ "$1" = "-l" -a $# -lt 3 ]
then
echo "Content of katalogos will be sorted numerically and blank lines will be excluded!"
sort -b -n katalogos
elif [ "$1" = "-s" -a $# -lt 4 ]
if [[ $2 != *[!0-9]* ]]
then
echo "Content of katalogos will be sorted according to the second argument!"
sort +$3 katalogos
fi
elif [ "$1" = "-c" -a $# -lt 4 ] // syntax error
if [[ $2 = *[!0-9]* ]]
then
echo "Content of katalogos will be sorted according to the keyword!"
if [ $(grep -e "$2" katalogos | wc -l) -eq 0 ]
then
echo "String is not matched."
else
grep -e "$2" katalogos
fi
fi
elif [ "$1" = "-d" -a ( "$3" = "-b" -o "$3" = "-r" ) ]
if [[ $2 = *[!0-9]* ]]
then
echo "Katalogos's string matching lines will be deleted and blank lines will be in their place, assuming that the third argument equals -b, else just the lines will be deleted!"
if [ $(grep -e $2 katalogos | wc -l) -eq 0 ]
then
echo "String is not matched."
else
if [ "$3" = "-b" ]
then
sed -i "$3" katalogos | sed -i '$ a '
echo "A blank line inserted in place of the deleted one."
else
sed -i "$3" katalogos
echo "Line deleted."
fi
fi
fi
elif [ "$1" = "-n" ]
echo "katalogos's number of blank lines will be shown with the ability to delete them!"
grep -cvP '\S' katalogos
read -p "Do you want to delete them? Type 1 for yes or 0 for no... " ans
if [ $ans -eq 1 ]
then
grep -cvP '\S' file | sed -i
echo "Lines deleted."
fi
else
echo "Help centre!"
echo "-Type ./telcat -a to insert a new line to katalogos."
echo "-Type ./telcat -l to see the contents of katalogos sorted numerically (excluding blank lines)."
echo "-Type ./telcat -s plus a number to see the contents of katalogos sorted by the data that the number points to."
echo "-Type ./telcat -c plus a keyword to see only the lines that match with the word given."
echo "-Type ./telcat -d plus a keyword and -b or -r to delete the lines that contain the word given. Specifically if the third argument is -b it will automatically add a blank line to the deleted one and if it is -r it will not."
echo "-Type ./telcat -n to see the number of blank lines of katalogos."
echo "End of help centre!"
fi

Losing newlines when reading from stdin

I have been beating my head up about this.
I wanted to loop over a multiline string character by character in bash but was loosing all newlines. First thing I did when i didn't find any obvious error was to run shellcheck on it, it seemed fine with the program.
script.sh:
#!/usr/bin/env bash
transform_single() {
if [[ $# -ne 1 ]]; then
echo 'Error: illegal number of args' 1>&2
fi
equation=''
delim0=0
delim="$1"
while IFS= read -rn1 c; do
if [[ $delim0 -eq 0 ]] && [[ "$c" == "$delim" ]]; then
delim0=1
equation=''
elif [[ $delim0 -ne 0 ]] && [[ "$c" == "$delim" ]]; then
delim0=0
echo -n "$equation" | texmath
elif [[ $delim0 -ne 0 ]]; then
equation="$equation$c"
else
echo -n "$c"
fi
done
}
transform_single '$'
input.txt:
<newlines>
<newlines>
# Hello world!
<newlines>
This is a test string.
<newlines>
invocation:
bash script.sh < input.txt
output:
# Hello world!This is a test string.
excepted output:
The same as in the input file.
Working script
#!/bin/bash
transform_single() {
if (($# != 1)); then echo 'Error: illegal number of args' 1>&2; fi
equation=''
delim0=0
delim="$1"
while IFS= read -r -d $'\0' -n 1 c; do
if ((delim0 == 0)) && [[ "$c" == "$delim" ]]; then
delim0=1
equation=''
elif ((delim0 != 0)) && [[ "$c" == "$delim" ]]; then
delim0=0
echo -n "$equation" | texmath
elif ((delim0 != 0)); then
equation="$equation$c"
else
echo -n "$c"
fi
done
}
transform_single '$'
The issue is that you must set a delimiter to read, a null character, to preserve line feed.

Shell SH : how to find if a string is present in a variable with egrep?

For a small script shell sh
I would like to know if "of" or "the" or "is" is present in the variable Toto
Toto="Planet of the world"
Test= $(egrep -c '(of|the|is)' "$Toto")
if $Test > 0; then echo "OK"; else echo "NO"
But this code does not work ....
Somebody could help me ?
Toto="Planet of the world"
Test=$(echo $Toto | grep -c "of\|the\|is")
if [[ $Test -gt 0 ]]
then
echo "OK";
else
echo "NO";
fi
Shorter :
Toto="Planet of the world"
Test=$(echo $Toto | grep -c "of\|the\|is")
[[ $Test -gt 0 ]] && echo "OK" || echo "NO";
Try with a pipeline, like this:
$ Toto="Planet of the world"
$ test="$Toto | egrep '(of|the|is)'"
$ if [ "$test" > 0 ] ; then echo 'OK'; else echo 'NO'; fi

unary operator expected with more than 1 argument

for var in "$#"
do
if test -z $var
then
echo "missing operand"
elif [ -d $var ]
then
echo "This is a directory"
elif [ ! -f $var ]
then
echo "The file does not exist"
else
basename=$(basename $var)
dirname=$(readlink -f $var)
inodeno=$(ls -i $var| cut -d" " -f1)
read -p "remove regular file $#" input
if [ $input = "n" ]
then exit 1
fi
mv $var "$var"_"$inodeno"
echo "$basename"_"$inodeno":"$dirname" >> $HOME/.restore.info
mv "$var"_"$inodeno" $HOME/deleted
fi
done
**Hello, the above code is trying to mimic the rm command in unix. Its purpose is to remove the file .
Eg if I type in bash safe_rm file1 , it works however if type in
bash safe_rm file1 file 2 , it prompts me to remove file 1 twice and gives me a unary operater expected for line 27(if [ $input = "n" ]).
Why does it not work for two files, ideally I would like it to prompt me to remove file1 and file 2.
Thanks
read -p "remove regular file $#" input
should probably be
read -p "remove regular file $var" input
That's the basic.
And this is how I'd prefer to do it:
for T in "$#"; do
if [[ -z $T ]]; then
echo "Target is null."
elif [[ ! -e $T ]]; then
echo "Target does not exist: $T"
elif [[ -d $T ]]; then
echo "Target can't be a directory: $T"
else
BASE=${T##*/}
DIRNAME=$(exec dirname "$T") ## Could be simpler but not sure how you want to use it.
INODE_NUM=$(exec stat -c '%i' "$T")
read -p "Remove regular file $T? "
if [[ $REPLY == [yY] ]]; then
# Just copied. Not sure about its logic.
mv "$T" "${T}_${INODE_NUM}"
echo "${BASE}_${INODE_NUM}:${DIRNAME}" >> "$HOME/.restore.info"
mv "${T}_${INODE_NUM}" "$HOME/deleted"
fi
fi
done

Using sh -c if comparisons inside an SSH command

I'm having some trouble with the != section of the if statement. Essentially this statement is valid as far as I'm aware, however executing this gives [: 1: !=: unexpected operator. I've tried executing using -n but for whatever reason, even if the output is blank, using -n still runs the echo command.
Any help on this is appreciated. I've attached the code snippet below.
#!/bin/sh
HOST=$1
USER="/scripts/whoowns $HOST | tr -d '\r'"
ssh -t $HOST -p 22 -l deehem "sh -c 'if [ "" != "\`$USER\`" ]; then echo "Username for $HOST: \`$USER\`"; fi' ; bash -login"
As you realised, "bla "" bla" is just two strings concatenated ("bla bla").
You can escape the ": \", but the standard [ test tool has an option specifically for this task:
-n STRING
the length of STRING is nonzero
-z STRING
the length of STRING is zero
Note: why do you have \`? That way the string is never going to be empty....
In regards to your "however executing this gives [: 1: !=: unexpected operator" problem, here is a solution:
Use bash -c instead of sh -c. The bash program seems to be better than sh at handling square brackets. For example:
ubuntu#ubuntu:/$ echo "antipetalous" | if [[ "antipetalous" =~ "ti" ]]; then echo "match"; else echo "no"; fi
match
ubuntu#ubuntu:/$ echo "antepetalous" | if [[ "antepetalous" =~ "ti" ]]; then echo "match"; else echo "no"; fi
no
ubuntu#ubuntu:/$ sh -c 'echo "antipetalous" | if [[ "antipetalous" =~ "ti" ]]; then echo "match"; else echo "no"; fi'
sh: 1: [[: not found
no
ubuntu#ubuntu:/$ bash -c 'echo "antipetalous" | if [[ "antipetalous" =~ "ti" ]]; then echo "match"; else echo "no"; fi'
match
ubuntu#ubuntu:/$ bash -c 'echo "antepetalous" | if [[ "antepetalous" =~ "ti" ]]; then echo "match"; else echo "no"; fi'
no
ubuntu#ubuntu:/$ sh -c 'echo "antepetalous" | if [[ "antepetalous" =~ "ti" ]]; then echo "match"; else echo "no"; fi'
sh: 1: [[: not found
no
ubuntu#ubuntu:/$
So ssh -t $HOST -p 22 -l deehem "sh -c 'if [ "" != ... would become ssh -t $HOST -p 22 -l deehem "bash -c 'if [ "" != ....
Thanks to pLumo at https://askubuntu.com/questions/1310106/sh-c-sh-not-working-when-using-if-statement-and-having-in-the-filena ("command line - sh -c '...' sh {} not working when using if statement and having ' in the filename - Ask Ubuntu").

Resources