String manipulation Bash-Extensions - bash

In my script I'm trying to take a string, then output the extension of a string if it has one. So essentially I take the basename of a file, then output anything that comes after a period.
What's the syntax to do something like this?
For example
dotcutter.sh
file=testfile.jpg
the script should output .jpg
EDIT:
I've solved my problem now with:
file=$(basename "$1" )
stub=${file%.*}
echo ${file#"$stub"}
Which reduces my argument to a basename, thank you all.

$ file=testfile.jpg
$ echo ${file##*.}
jpg
$ file=testfile.ext1.ext2
$ echo ${file##*.}
ext2
$ file=noextension
$ echo ${file##*.}
noextension
Notice that it doesn't work if the file has no extension. If that's important then try this two-step solution:
$ file=testfile.ext1.ext2
$ stub=${file%.*}
$ echo ${file#"$stub"}
.ext2
Or this regex-based one, which will only call echo if there's actually an extension. (&& is shorthand for "if then".)
$ regex='(\.[^.]*)$'
$ file=testfile.ext1.ext2
$ [[ $file =~ $regex ]] && echo ${BASH_REMATCH[1]}
.ext2
$ file=noextension
$ [[ $file =~ $regex ]] && echo ${BASH_REMATCH[1]}
See also:
basename(1)
dirname(1)
Bash FAQ: How can I use parameter expansion? How can I get substrings? How can I get a file without its extension, or get just a file's extension?]

Try the following code :
file=testfile.jpg
echo .${file#*.}
That use parameter expansion

Related

Grep only string in a line in shell script

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

Shell script for replacing characters?

I'm trying to write a shell script that takes in a file(ex. file_1_2.txt) and replaces any "_" with "."(ex. file.1.2.txt). This is what I have but its giving me a blank output when I run it.
read $var
x= `echo $var | sed 's/\./_/g'`
echo $x
I'm trying to store the changed filename in the variable "x" and then output x to the console.
I am calling this script by writing
./script2.sh < file_1_2.txt
There is two problems. First, your code has some bugs:
read var
x=`echo $var | sed 's/_/\./g'`
echo $x
will work. You had an extra $ in read var, a space too much (as mentioned before) and you mixed up the replacement pattern in sed (it was doing the reverse of what you wanted).
Also if you want to replace the _ by . in the filename you should do
echo "file_1_2.txt" | ./script2.sh
If you use < this will read the content of `file_1_2.txt" into your script.
Another solution, with bash only:
$ x=file_1_2.txt; echo "${x//_/.}"
file.1.2.txt
(See “Parameter expansion” section in bash manual page for details)
And you can also do this with rename:
$ touch file_1_2.txt
$ ls file*
file_1_2.txt
$ rename 'y/_/\./' file_1_2.txt
$ ls file*
file.1.2.txt
Threre is not need for sed as bash supports variable replacement:
$ cat ./script2
#!/bin/bash
ofile=$1
nfile=${ofile//_/./}
echo mv "$ofile" "$nfile"
$ ./script2 file_1_2.txt
mv "file_1_2.txt" "file.1.2.txt"
Then just remove echo if you are satisfied with the result.

Bash Scripting: greping the parameter

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

Parameter Substitution - Remove the part of the string after the pattern

Let's say I have a path which looks like the following:
/A/B/C/DIRECTORY/D/E/F
Now, what I want to achieve using parameter substitution, is cutting of the part of the path after DIRECTORY, no matter where in the path the DIRECTORY is positioned (A, B, C, etc. just stand for random directory names).
After substitution:
/A/B/C/DIRECTORY
This is what I've tried so far:
#!/bin/bash
if [[ $# < 1 ]]
then
echo "Usage: $0 DIRECTORY"
fi
CURRENT_DIRECTORY=$(pwd)
DIRECTORY=$1
cd ${CURRENT_DIRECTORY%!(DIRECTORY)/*}
Obviously, this doesn't work. I could implement this using awk or sed but I'm interested if it is possible using only parameter substitution.
May be this can help -
[jaypal:~/Temp] D="A/B/C/DIRECTORY/D/E/F"
[jaypal:~/Temp] echo $D
A/B/C/DIRECTORY/D/E/F
[jaypal:~/Temp] c=${D%/*/*/*}
[jaypal:~/Temp] echo $c
A/B/C/DIRECTORY
[ghoti#pc ~]$ D="/A/B/C/foo/D/E"
[ghoti#pc ~]$ echo "${D/foo*/}"
/A/B/C/
of course, this isn't perfect:
[ghoti#pc ~]$ D="/A/B/C/foobar/D/foo/E"
[ghoti#pc ~]$ echo "${D/foo*/}"
/A/B/C/
Read the bash man page and search for "Pattern substitution".
Try next solution:
cd ${CURRENT_DIRECTORY/${DIRECTORY}*/""}
EDIT:
More accurate answer would be appending your directory after removing last part:
cd ${CURRENT_DIRECTORY/${DIRECTORY}*/""}$DIRECTORY
Thanks to Birei, I came to this (not perfect but good enough solution:
#/bin/bash
if [[ $# < 1 ]]
then
echo "Usage: $0 BASENAME"
fi
echo ${PWD/%$1*/$1}
Example:
$ PWD=/home/ltorvalds/workspace
$ ./up.sh ltorvalds
/home/ltorvalds

How would I use grep on a single word in UNIX?

I want to run a script in unix that will look for a specific pattern inside a passed argument. The argument is a single word, in all cases. I cannot use grep, as grep only works on searching through files. Is there a better unix command out there that can help me?
Grep can search though files, or it can work on stdin:
$ echo "this is a test" | grep is
this is a test
Depending on what you're doing you may prefer to use bash pattern matching:
# Look for text in $word
if [[ $word == *text* ]]
then
echo "Match";
fi
or regular expressions:
# Check is $regex matches $word
if [[ $word =~ $regex ]]
then
echo "Match";
fi
you can use case/esac as well. No need to call any external commands (for your case)
case "$argument" in
*text* ) echo "found";;
esac
As of bash 3.0 it has a built in regexp operator =~
Checkout http://aplawrence.com/Linux/bash-regex.html
if echo $argument | grep -q pattern
then
echo "Matched"
fi
my File is:
$ cat > log
loga
hai how are you loga
hai
hello
loga
My command is:
sed -n '/loga/p' log
My answer is:
loga
hai how are you loga
loga

Resources