I writing a shell script.
The line will look like:
"holderIdentity":"leader-elector1-5cd5b9d76d-ztfgf","numberofLeader":{"":0,"node2":1,"node3":2,"node4":2}"
The character 5cd5b9d76d-ztfgf will be created randomly, so my keyword to grep is just only leader-elector. And the string ,"numberofLeader":{"":0,"node2":1,"node3":2,"node4":2}" is also randomly (it is diffent everytime)
How can I get just this string leader-elector1-5cd5b9d76d-ztfgf from the line.
Thank you so much!
using GNU grep
grep -Eo 'leader-elector[^"]*' <<< '"holderIdentity":"leader-elector1-5cd5b9d76d-ztfgf","numberofLeader":{"":0,"node2 ":1,"node3":2,"node4":2}"'
otherwise with bash regex feature
var='"holderIdentity":"leader-elector1-5cd5b9d76d-ztfgf","numberofLeader":{"":0,"node2 ":1,"node3":2,"node4":2}"'
re='leader-elector[^"]*'
if [[ $var =~ $re ]] ; then
declare -p BASH_REMATCH
echo "${BASH_REMATCH[0]}"
fi
Related
ns/APAC_BankTransfers_Publish/CMB/services/svcPublishBankTransfers/flow.xml
In the above line and similar lines like this I want to extract whatever is present in between services and flow.xml and save it to a variable DIST.
The output should be svcPublishBankTransfers.
Using parameter expansion mechanisms available in POSIX sh:
s=ns/APAC_BankTransfers_Publish/CMB/services/svcPublishBankTransfers/flow.xml
s=${s%/flow.xml} # remove "/flow.xml"
s=${s##*/services/} # remove everything before "services"
echo "$s"
This has the advantages of being purely in-process (so faster than approaches that require piping through an external tool), and compatible with all POSIX shells (ash, dash, ksh, etc).
References:
BashFAQ #100 ("How do I do string manipulation in bash?")
BashFAQ #73 ("How can I use parameter expansion? How can I get substrings?")
Using BASH regex:
s='ns/APAC_BankTransfers_Publish/CMB/services/svcPublishBankTransfers/flow.xml'
[[ "$s" =~ /([^/]+)/[^/]*$ ]] && echo "${BASH_REMATCH[1]}"
svcPublishBankTransfers
OR else:
[[ "$s" =~ /services/([^/]+)/flow\.xml ]] && echo "${BASH_REMATCH[1]}"
svcPublishBankTransfers
bash$ echo "ns/APAC_BankTransfers_Publish/CMB/services/svcPublishBankTransfers/flow.xml" | cut -d '/' -f 5
svcPublishBankTransfers
bash$
I'm trying to write a small script that either takes input from a file or from user, then it gets rid of any blank lines from it.
I'm trying to make it so that if there is no file name specified it will prompt the user for input. Also is the best way to output the manual input to a file then run the code or to store it in a variable?
So far I have this but when I run it with a file it give 1 line of error before returning the output I want. The error says ./deblank: line 1: [blank_lines.txt: command not found
if [$# -eq "$NO_ARGS"]; then
cat > temporary.txt; sed '/^$/d' <temporary.txt
else
sed '/^$/d' <$#
fi
Where am I going wrong?
You need spaces around [ and ]. In bash, [ is a command and you need spaces around it for bash to interpret it so.
You can also check for the presence of arguments by using (( ... )). So your script could be rewritten as:
if ((!$#)); then
cat > temporary.txt; sed '/^$/d' <temporary.txt
else
sed '/^$/d' "$#"
fi
If you want to use only the first argument, then you need to say $1 (and not $#).
Try using this
if [ $# -eq 0 ]; then
cat > temporary.txt; sed '/^$/d' <temporary.txt
else
cat $# | sed '/^$/d'
fi
A space is needed between [ and $# and your usage of $# is not good. $# represents all arguments and -eq is used to compare numeric values.
There are multiple problems here:
You need to leave a space between the square brackets [ ] and the variables.
When using a string type, you cannot use -eq, use == instead.
When using a string comparison you need to use double square brackets.
So the code should look like:
if [[ "$#" == "$NO_ARGS" ]]; then
cat > temporary.txt; sed '/^$/d' <temporary.txt
else
sed '/^$/d' <$#
fi
Or else use $# instead.
Instead of forcing user input to a file, I'd force the given file to stdin:
#!/bin/bash
if [[ $1 && -r $1 ]]; then
# it's a file
exec 0<"$1"
elif ! tty -s; then
: # input is piped from stdin
else
# get input from user
echo "No file specified, please enter your input, ctrl-D to end"
fi
# now, let sed read from stdin
sed '/^$/d'
The output is blank fr the below script. What is it missing? I am trying to grep a string
#!/bin/ksh
file=$abc_def_APP_13.4.5.2
if grep -q abc_def_APP $file; then
echo "File Found"
else
echo "File not Found"
fi
In bash, use the <<< redirection from a string (a 'Here string'):
if grep -q abc_def_APP <<< $file
In other shells, you may need to use:
if echo $file | grep -q abc_def_APP
I put my then on the next line; if you want your then on the same line, then add ; then after what I wrote.
Note that this assignment:
file=$abc_def_APP_13.4.5.2
is pretty odd; it takes the value of an environment variable ${abc_def_APP_13} and adds .4.5.2 to the end (it must be an env var since we can see the start of the script). You probably intended to write:
file=abc_def_APP_13.4.5.2
In general, you should enclose references to variables holding file names in double quotes to avoid problems with spaces etc in the file names. It is not critical here, but good practices are good practices:
if grep -q abc_def_APP <<< "$file"
if echo "$file" | grep -q abc_def_APP
Yuck! Use the shell's string matching
if [[ "$file" == *abc_def_APP* ]]; then ...
Here is my problem. I have script and I want to make sure that the parameter that is entered when the script is called matches a variable name inside the script.
For example:
./valid foo <- being the script call
#!/bin/bash
PARAM=$1
VAR=/foo/
if grep -c $PARAM == $VAR
then
echo yes
fi
echo no
I am having the worst time using grep, I'm not sure how to use it properly inside of a script and after scouring the internet I think I need some specific feedback on my problem.
Thanks,
EA
This is not robust, but you can do:
if echo "$VAR" | grep -q "$PARAM"; then
It is probably better to simply do:
if test "$VAR" = "$PARAM"; then
If you are trying to match a regex, bash allows:
if [[ "$VAR" =~ "$PARAM" ]]; then
to match the fixed string $VAR against the regex $PARAM. If $VAR is the regex, you should reverse the order of the arguments. (That is, [[ "$PARAM" =~ "$VAR ]].)
You could search inside your script, since the declaration is the name followed by an equal sign:
if egrep "^\s*$PARAM=" $0
then
echo yes
else
echo no
fi
to list variables use
set -o posix ; set
the posix thingie prevents listing of functions.
In order to isolate parameters local to script, run it from the shell and store the result,
then run it from your script and compare output
(set -o posix ; set) >/tmp/variables.before
(set -o posix ; set) >/tmp/variables.after
The command:
value=${value%?}
will remove the last character from a variable.
Is there any logical reason why it would not work from within a script?
In my script it has no effect whatsoever.
if [[ $line =~ "What I want" ]]
then
if [[ $CURRENT -eq 3 ]]
then
echo "line is " $line
value=`echo "$line" | awk '{print $4}'`
echo "value = "$value
value=${value%?}
echo "value = $value "
break
fi
fi
I cant post the whole script, but this is the piece I refer to. The loop is being entered properly, but the 2 echo $value lines return the same thing.
Edit - this question still stands. The code works fine line bu line in a terminal, but all together in a script it fails.
Echo adds an extra line character to $value in this line:
value=`echo "$line" | awk '{print $4}'`
And afaik that extra char is removed with %?, so it seems it does not change anything at all.
Try echo -n instead, which does not add \n to the string:
value=`echo -n "$line" | awk '{print $4}'`
Since you have provided only the relevant part in the code and not the whole file, I'm going to assume that the first line of your file reads `#!/bin/sh'. This is your problem. What you are trying to do (parameter expansion) is specific to bash, so unless /bin/sh points to bash via a symlink, then you are running the script in a shell which does not understand bash parameter expansion.
To see what /bin/sh really is you can do: ls -l /bin/sh. And to remedy the situation, force the script to run in bash by changing the `shebang' at the top to read `#!/bin/bash'