use of sed substitute in shell script doesn't work - linux

I have made an install script which basically inserts some RewriteRule right after RewriteEngine On line by using sed inside a shell script
#!/bin/bash
REWRITE_RULE="RewriteRule \^catalog\/category\/view\/id\/([0-9]+)$ http:\/\/localhost\/app\/#?c=$1 [NE,L,R=301]"
FILE_PATH=".htaccess"
sed -i "s/RewriteEngine on/RewriteEngine on\n\n$REWRITE_RULE/g" $FILE_PATH
it does nothing but gives some error like
: No such file or directory
I tried same commands in shell and it worked without any issues and updated my .htaccess file
I am new to shell scripting so don't know the difference of using same command through shell and through script.. please guide

The script itself is fine. Are you sure that the lines posted above are exactly as you took them from your script?
The error message indicates that you provided an empty name as the filename, thus I suggest you put a
echo "FILE_PATH: $FILE_PATH"
directly before your sed command in order to check whether the variable is set correctly.

You'll find that your script contains carriage returns due to being saved with DOS end-of-line characters. Use tr -d '\r' <brokenscript >fixedscript to fix your script.
Here's a copy of a session with the problem reproduced and fixed:
$ cat file
var=foo
$ cat myscript
sed -i s/foo/bar/ file
$ bash myscript
: No such file or directory
$ shellcheck myscript
In myscript line 1:
sed -i s/foo/bar/ file
^-- SC1017: Literal carriage return. Run script through tr -d '\r' .
$ tr -d '\r' < myscript > fixedscript
$ bash fixedscript
$ cat file
var=bar
$

Related

How can I replace a line of text in a file with a single command when the line contains a variable?

I have a script called script.sh which has the contents
export HELLO=$WORLD
I want to change it using a single command to
export HELLO=${WORLD:2:3}
I'm attempting to use the sed command but i'm new to linux and can't quite get it right. Here's what I have
sed -i 's/export HELLO=$WORLD/export HELLO=${WORLD:2:3}' script.sh
How should this line be written to replace the text correctly?
You just missed a / at the very end:
sed -i 's/export HELLO=$WORLD/export HELLO=${WORLD:2:3}/' script.sh
^
this / is missing
The $ is a special symbol that means end of line, also as #yvesonline points out you are missing the trailing /. This is how I would do it:
sed -i 's/\(export HELLO=\$\)\(WORLD\)/\1{\2:2:3}/' script.sh

bash script file copied with additional character in filename

I am writing a bash script to copy some config files. I run the file using sudo bash configure.sh.
#!/bin/bash
cp config/ocr_pattern /usr/share/tesseract-ocr/tessdata/ocr_pattern
cp config/ocr_config /usr/share/tesseract-ocr/tessdata/tessconfigs/ocr_config
However when I view the changes made, ocr_config is copied correctly but ocr_pattern is copied with ocr_pattern? as the filename instead of ocr_pattern. There is an additional character ? behind in the filename for ocr_pattern. What is the issue here?
cat -A
#!/bin/bash^M
cp config/ocr_pattern /usr/share/tesseract-ocr/tessdata/ocr_pattern^M
cp config/ocr_config /usr/share/tesseract-ocr/tessdata/tessconfigs/ocr_config
As shown by the output of cat -A, you have carriage return (\r) at the end of some lines causing the mentioned issues.
Remove those:
sed -i 's/\r$//' configure.sh
or just use dos2unix:
dos2unix configure.sh

awk not being recognized after certain command

Here's a MWE:
#!/bin/bash
INFILE=$1
echo `echo $INFILE | awk '{print(substr($0,8,3))}'`
PATH=${INFILE%/*}
echo `echo $INFILE | awk '{print(substr($0,8,3))}'`
exit
Apparently the first awkcommand runs fine, but in the second command bash doesn't recognize awkanymore!
This is what I get running it (assuming that f_mwe.sh is the name of the file):
$ ./f_mwe.sh /home/something/path/this_is_the_name.txt
ome
./f_mwe.sh: line 31: awk: command not found
$
I have tried defining /bin/sh and ksh at the beginning also but got the same results. I have no idea what's causing this.
Any help is appreciated.
You are overwriting the PATH variable and not appending to it I believe. You should append to the PATH variable.

How can I execute list of commands from a file in Bash Shell Script

I have a file "commands.txt" with some commands in it for example:
pwd
wc -l commands.txt
And when I run the following command, its not executing the commands.
export IFS=$'\n' (I did this so that I could avoid breaking up the command line from the file)
for i in `cat commands.txt`; do $i; done
Any help would be greatly appreciated.
Regards,
RSR
Since you are setting IFS to \n, your second line wc -l commands.txt is not being word-split correctly and is being treated as a single command instead of the command wc followed by parameter commands.txt. Do not set IFS, use a while loop instead
while read -r com;
do
$com;
done < commands.txt

How to test linux variable within sed file?

I have a sed file that contains contains a few substitutions, it is executed on a file using the following syntax:
sed -f mysedfile file.txt > fixed_file.txt
I would like to test a system variable and depending what that variable contains, execute different sed operations on file.txt.
Would it be possible to put this logic into mysedfile?
Thank you for the help.
Perl was explicitly created to get around limitations of sed and awk. The -p mode runs a script for each line in the file. You can put it on the commandline:
perl -p -e "s/foo/\$ENV{'HOME'}/e" < files.txt
Or move the script to a file (you can remove the '\' before the $)
perl -p file.pl < files.txt
Or make the first line of your script like this so you can run it directly.
#!/usr/bin/perl -p

Resources