delete substring from env variable doesn't work in shell - shell

I was trying to delete a path from my PATH variable using the shell string manipulation approach: ${string%$substring}. It works for common variable but it doesn't work when I want to delete a path in PATH variable.
xiangxue➜~» echo $PATH [10:34:16]
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/xiangxue/anaconda2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin
Suppose I would like to delete :/usr/games entry from PATH, I did this:
xiangxue➜~» echo ${PATH%:/usr/games} [10:40:12]
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/xiangxue/anaconda2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin
The PATH doesn't delete :/usr/games entry, and it looks exactly same.

The ${parameter%pattern} string manipulation removes from the end of the string (see the Bash Guide on Parameter Expansion or the Bash Reference manual or the POSIX Spec) but :/usr/games isn't at the end of your string so it doesn't match.
The expansion you want for this is the ${parameter/pat/string} expansion:
echo "${PATH/:\/usr\/games}"
Alternatively you want to split $PATH on : and loop to filter out your desired entry.

try this;
PATH=$(echo $PATH | sed 's/:\/usr\/games:/:/g;s/:\/usr\/games//g;s/\/usr\/games://g')
user#host:/tmp$ PATH=/usr/games:/usr/sbin:/usr/bin:/sbin:/usr/games:/bin:/usr/games
user#host:/tmp$ echo $PATH
/usr/games:/usr/sbin:/usr/bin:/sbin:/usr/games:/bin:/usr/games
user#host:/tmp$ PATH=$(echo $PATH | sed 's/:\/user\/games:/:/g;s/:\/usr\/games//g;s/\/usr\/games://g')
user#host:/tmp$ echo $PATH
/usr/sbin:/usr/bin:/sbin:/bin

Related

Loop function using urls as input for the filenames [duplicate]

I am trying to get "abc.txt" out of /this/is/could/be/any/path/abc.txt using Unix command.
Note that /this/is/could/be/any/path is dynamic.
Any idea?
In bash:
path=/this/is/could/be/any/path/abc.txt
If your path has spaces in it, wrap it in "
path="/this/is/could/be/any/path/a b c.txt"
Then to extract the path, use the basename function
file=$(basename "$path")
or
file=${path##*/}
basename path gives the file name at the end of path
Edit:
It is probably worth adding that a common pattern is to use back quotes around commands e.g. `basename ...`, so UNIX shells will execute the command and return its textual value.
So to assign the result of basename to a variable, use
x=`basename ...path...`
and $x will be the file name.
You can use basename /this/is/could/be/any/path/abc.txt
You can use dirname command
$ dirname $path

Assign a variable in a bash script dynamically that parses a os path

I seem to be not able to get this right
When i run this code I need a variable for the filename later on. How should I do thi?
#!/bin/bash
foo="../../../data/audio/serval-data/wav-16bit-16khz/ytdl/balanced_train/vidzyGjrJfE_rg.wav"
echo $foo
echo "${foo%.*}" | cut -d "/" -f10;
# fid=vidzyGjrJfE_rg
I want to use new variable fid to have value "vidzyGjrJfE_rg"
You can use a couple of iterations of shell builtins for this (see #melpomene's answer) but FYI that's exactly what basename exists to do:
$ foo="../../../data/audio/serval-data/wav-16bit-16khz/ytdl/balanced_train/vidzyGjrJfE_rg.wav"
$ fid=$(basename "$foo" '.wav')
$ echo "$fid"
vidzyGjrJfE_rg
You can do it like this:
fid="${foo##*/}"
fid="${fid%.*}"
Just as % removes a matching suffix from a variable, # removes a prefix (and ## removes the longest matching prefix). See https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion.

Bash replace string

I'm working on a script which checks if file exists. If it exists then I want to get the route.
What I did is the following:
RESULT_=$(find $PWD -name someRandom.json)
This returns the path to the file:
/Users/guest/workspace/random_repo/random/some_folder/someRandom.json
I'm stuck in the way to navigate among files. Is there a way of replacing someRandom.json with '' so I can do:
cd /Users/guest/workspace/random_repo/random/some_folder/
I tried using the solution provided here but it isn't working. I tried the following:
RESULT=$($RESULT/someRandom.json/'')
echo $RESULT
And this returns no such file or directory.
given:
$ echo "$result"
/Users/guest/workspace/random_repo/random/some_folder/someRandom.json
You can get the file name:
$ basename "$result"
someRandom.json
Or the path:
$ dirname "$result"
/Users/guest/workspace/random_repo/random/some_folder
Or you can use substring deletion:
$ echo "${result%/*}"
/Users/guest/workspace/random_repo/random/some_folder
Or, given the file name and the full path, just remove the file name:
$ echo "$tgt"
someRandom.json
$ echo "${result%"$tgt"}"
/Users/guest/workspace/random_repo/random/some_folder/
There are many examples of Bash string manipulation:
BashFAQ/100
BashFAQ/073
Bash Hacker's Parameter Expansion
Side note: Avoid using CAPITAL_NAMES for Bash variables. They are reserved for Bash use by convention...
You want parameter expansion, not command substitution.
RESULT="${RESULT%/*}/"

bash: get directory from certain part of path onwards

I have an arbitrary path which contains the directory mydir:
/some/path/to/mydir/further/path/file.ext
I want to get the part after mydir, in this example:
/further/path/file.ext
Please note that the levels of subdirectories are also arbitrary, so a path like
/yet/another/long/path/to/mydir/file.ext
is also possible (where the result would be "file.ext")
The first occurrence of mydir should be used, so the path
/path/mydir/some/other/path/mydir/path/file.ext
should result in
/some/other/path/mydir/path/file.ext
How can one do this with bash?
Note. It is assumed that mydir will always appear enclosed between slashes.
after=${mydir#*/mydir/}
if [ "$mydir" = "$after" ]; then
fail_with_error "Path does not contain /mydir/"
fi
after="/$after"
In line 1, the # means substring after, and the * is the usual placeholder. To be safe against directories like .../mydirectaccess/... I included the slashes at both ends of mydir. Line 5 just prepends the slash that had been taken off by line 1.
Using Shell Parameter Expansion:
$ mydir="/some/path/to/mydir/further/path/file.ext"
$ echo ${mydir#*mydir}
/further/path/file.ext
$ mydir="/path/mydir/some/other/path/mydir/path/file.ext"
$ echo ${mydir#*mydir}
/some/other/path/mydir/path/file.ext
Go through sed. Example:
echo /some/path/to/mydir/further/path/file.ext | sed 's/.*mydir/mydir/'
Using bash, you can do something like this:
V=/yet/another/long/path/to/mydir/file.ext
R=${V#*mydir/}
echo $R
file.ext

use bash $HOME in shell script

How to made bash to execute variable value.
For example, we have this code, where variable value was set in single quotes(!).
#!/bin/bash
V_MY_PATH='$HOME'
echo "$V_MY_PATH"
ls $V_MY_PATH
The output is
$HOME
ls: $HOME: No such file or directory
How to made bash to translate shell variable insto its value if there is some.
I want to add some code after V_MY_PATH='$HOME' to make output like echo $HOME.
It's something simple, but i'm stuck.
(NB: I know that with V_MY_PATH="$HOME", it works fine.)
EDIT PART:
I just wanted to make it simple, but I feel that some details are needed.
I'm getting parameter from a file. This part works good. I don't want to rewite it.
The problem is that when my V_MY_PATH contains a predefined variable (like $home) it's not treated like its value.
Remove the single quotes
V_MY_PATH='$HOME'
should be
V_MY_PATH=$HOME
you want to use $HOME as a variable
you can't have variables in single quotes.
Complete script:
#!/bin/bash
V_MY_PATH=$HOME
echo "$V_MY_PATH"
ls "$V_MY_PATH" #; Add double quotes here in case you get weird filenames
Output:
/home/myuser
0
05430142.pdf
4
aiSearchFramework-7_10_2007-v0.1.rar
etc.
use variable indirect reference so:
pete.mccabe#jackfrog$ p='HOME'
pete.mccabe#jackfrog$ echo $p
HOME
pete.mccabe#jackfrog$ ls ${p}
ls: cannot access HOME: No such file or directory
pete.mccabe#jackfrog$ ls ${!p}
bash libpng-1.2.44-1.el6 python-hwdata squid
...
pete.mccabe#jackfrog$
The ${!p} means take the value of $p and that value is the name of the variable who's contents I wish to reference
Use eval command:
#!/bin/bash
V_MY_PATH='$HOME'
echo "$V_MY_PATH"
eval ls $V_MY_PATH
You can use single or double quotes, and in your case, none if you prefer.
You have nothing telling bash what the variable is equal to. Maybe something like this? (unless I misunderstand what you are trying to do)
======================================================================
#!/bin/bash
#########################
# VARIABLES #
#########################
V_MY_PATH=home
#########################
# SCRIPT #
#########################
echo "What is your home path?"
read $home
echo "Your home path is $V_MY_PATH"
ls $V_MY_PATH
Of course you could also just remove the variable at the top and use:
echo "Your home path is $home"

Resources