How to use variables in linux regex pattern? - linux

I need to execute a sed command with pattern /^03.06.2014/ in a .sh script & command line. The date is a variable not a constant. How could i implement this? When I use a variable inside a regex pattern, the command breaks. Do I need to escape something here? Any help is appreciated. Thanks!
date=$(date +%m.%d.%Y)
sed -n '/^$date/,$p' filename

Use double quotes for variable expansion in sed
sed -n "/^$date/,\$p" filename

You need to use double quotes to allow for shell expansion. You'll need to escape the $ meaning EOF.
sed -n "/^$date/,\$p" filename

Related

How do I run sed in TCL

I am trying to use TCLs builtin exec procedure to run the following sed shell command:
sed -i 's/"VALUE.${name}">.*</"VALUE.${name}">${value}</' ${dir}/imp.xml
However when I pass it to exec tcl errors out with
sed: -e expression #1, char 1: unknown command: `''
no idea how to interpret this.
I tried escaping the exec string:
exec {sed -i 's/"VALUE.${name}">.*</"VALUE.${name}">${value}</' ${dir}/imp.xml}
However this prevents the tcl variables from being expanded inside of the string.
Does anyone know what I need to do to get tcl to exec this sed program?
(my shell is csh if that is relevant)
The final solution involved 2 changes to the command string,
Escape all the double quote characters, (thanks #Chris Heithoff)
Single quotes are handled funny by TCL, replacing them with double quotes
(that are not escaped!) resolves the issue.
The final, working command string:
exec sed -i "s/\"VALUE.${name}\">.*</\"VALUE.${name}\">${alue}</" ${dir}/impl.xml
Each argument to the exec command must correspond to an individual argument at the shell command line, so enclosing everything in {} doesn't work.
Try this:, where all double quotes and dollar signs are escaped.
exec sed -i 's/\"VALUE.\${name}\">.*</\"VALUE.\${name}\">\${value}' \${dir}/impl.xml

how to escape file path in bash script variable

I would like to escape a file path that is stored in a variable in a bash script.
I read several threads about escaping back ticks or but it seems not working as it should:
I have this variable:
The variables value is entered during the bash script execution as user parameter
CONFIG="/home/teams/blabla/blabla.yaml"
I would need to change this to: \/home\/teams\/blabla\/blabla.yaml
How can I do that with in the script via sed or so (not manually)?
With GNU bash and its Parameter Expansion:
echo "${CONFIG//\//\\/}"
Output:
\/home\/teams\/blabla\/blabla.yaml
Using the solution from this question, in your case it will look like this:
CONFIG=$(echo "/home/teams/blabla/blabla.yaml" | sed -e 's/[]\/$*.^[]/\\&/g')
echo "/home/teams/blabla/blabla.yaml" | sed 's/\//\\\//g'
\/home\/teams\/blabla\/blabla.yaml
explanation:
backslash is used to set the following letter/symbol as an regular expression or vice versa. double backslash is used when you need a backslash as letter.
Why does that need escaping? Is this an XY Problem?
If the issue is that you are trying to use that variable in a substitution regex, then the examples given should work, but you might benefit by removing some of the "leaning toothpick syndrom", which many tools can do just by using a different match delimiter. sed, for example:
$: sed "s,SOME_PLACEHOLDER_VALUE,$CONFIG," <<< SOME_PLACEHOLDER_VALUE
/home/teams/blabla/blabla.yaml
Be very careful about this, though. Commas are perfectly valid characters in a filename, as are almost anything but NULLs. Know your data.

Shell How to get a new path by replacing a substring in a path string

I have a path like this:
dirname=../2Reconnaissance-annoted/J39/IMG_2208.json
I want to get a new path by replacing ".json" with "_json", so I tried this command:
tr "\.json" "_json" <<<$dirname
The problem is that I get:
__/2Reconnaissance-annoted/J39/IMG_2208_json
Rather than
../2Reconnaissance-annoted/J39/IMG_2208_json
How do you fix it, please?
tr does transliteration, i.e. it replaces a character by a character, not a string by a string. What you need is substitution.
Most shells support substitution directly:
dirname=${dirname/.json/_json}
(${dirname/%.json/_json} would only substitute the substrings at the end of the string).
If your shell doesn't support it, you can use sed:
echo "$dirname" | sed -e 's/\.json$/_json/'

search and replace string using sed

i have a sed command like this for search and replace string inside a file:
sed -i -e 's/`db1`./`db2`./g' result/files1.sql
that is working fine to replace the db1 to db2 inside the file of: result/files1.sql
however when i change it to bash and variable format, it does not work.
sed -i -e "s/`${mydbname}`./`${mydbname2}`./g" "${mypath}"
i get error like:
./mycoolscript: line 241: db1: command not found
./mycoolscript: line 241: db2: command not found
any solution would be great.
If is something you need to replace, you will need to escape by . Here it is
sed -i -e "s/\`${mydbname}\`./\`${mydbname2}\`./g" "${mypath}"
Escape the backtick character
sed -i -e "s/\`${mydbname}\`./\`${mydbname2}\`./g" "${mypath}"
Bash treats the part within backticks as a command and first executes that.
Try this
sed -i -e "s/${mydbname}/${mydbname2}/g" "${mypath}"
There is one more way, of using single quotes for literals & double quotes only around variables/escape sequences.
sed -i -e 's/`'"${mydbname}"'`./`'"${mydbname2}"'`./g' "${mypath}"
Because of single quotes, you will not have to escape the special characters.
The trade-off between escaping special characters vs. using mix of single & double quotes would depend on number of special characters vs. number of variables.
If there are too many characters that would need escaping & less number of variables, I would prefer mix of single & double quotes.

replace using sed

I want to replace IP dynamically but somehwo sed is placing word $IP instead of actual value.
IP=10.50.33.44
PORT=5774
sed -i~ 's/https:\/\/10.11.12.13:8443/https:\/\/$IP:$PORT/g' abc.txt
Can you help me out in getting the correct value?
Use double quotes" for variable expansion:
sed -i~ "s/https:\/\/10.11.12.13:8443/https:\/\/$IP:$PORT/g" abc.txt
and as #Joachim said, use different delimiter. For example,
sed -i~ "s;https://10.11.12.13:8443;https://$IP:$PORT;g" abc.txt
Variation on a theme: I always use single quotes to surround sed/awk/perl... commands as the shell can sometimes trip you up when using double quotes.
I find it best to double quote the variables:
sed -i~ 's/https:\/\/10.11.12.13:8443/https:\/\/'"$IP"':'"$PORT"'/g' abc.txt
As a "belt and braces" and as I usually compose my commands interactively at the command line in bash, the key-binding M-C-e (that's Alt-Control-e on most keyboards) will interpolate the command before it's sent. Letting you visually see what the command is really getting.

Resources