bash script file copied with additional character in filename - linux

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

Related

while copying the file to other file, giving error. cp: target is not a directory

When i am trying to run below code it is giving error of cp: target "Featurespath" is not a directory
I have tried multiple option but not working.
Featurespath=/permanent/jag/media-*/*/print/cooked/*Features.xml
for file in $(ls $Featurespath);
do
cat $Featurespath | sed "/pB-/s/Direction=\"unidir\"/Direction=\"bidir\"/" $Featurespath > /permanent/jag/temp.xml
cp -rf /permanent/jag/temp.xml $Featurespath
rm /permanent/jag/temp.xml
done
i want modified xml to be pasted in same xml file.
The error you received was because of the cp line: bash expands$Featurespath into a list of files. When cp sees more than 2 parameters, it assumes the last parameter to be a directory, which is not in this case. Here is my suggested fix:
Featurespath=/permanent/jag/media-*/*/print/cooked/*Features.xml
for file in $Featurespath
do
sed "/pB-/s/Direction=\"unidir\"/Direction=\"bidir\"/" "$file" > /permanent/jag/temp.xml
mv -f /permanent/jag/temp.xml "$file"
done
Notes
Do not use ls: bash can expand the wildcards just fine
Within the loop, you are now dealing with individual files $file, not the list of file $Featurespath
Do not need to use the cat command, the sed command can take a file name
sed has an inline editing option, which eliminate the need for temp file. You might want to look into it.
Replace cp/rm combination with mv
Ultimately, like others have said, sed is not the right tool to edit XML contents, but it might work for simple cases

perl -p -i -e inside a shell script

#!/usr/bin/env bash
DOCUMENT_ROOT=/var/www/html/
rm index.php
cd modules/mymodules/
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' `grep -ril y.yy.yy.y *`
shows shows a warning
-i used with no filenames on the command line, reading from STDIN.
It prevents running rest of the scripts.
Any solutions ?
Actually I need to run
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' `grep -ril y.yy.yy.y *`
Inside a shell script
I am using ubuntu with docker.
Let's look at this a step at a time. First, you're running this grep command:
grep -ril y.yy.yy.y *
This recursively searches all files and directories in your current directory. It looks for files containing the string "y.yy.yy.yy" in any case and returns a list of the files which contain this text.
This command will return either a list of filenames or nothing.
Whatever is returned from that grep command is then passed as arguments to your Perl command:
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' [list of filenames]
If grep returns a list of files, then the -p option here means that each line in every file in the list is (in turn) run through that substitution and then printed to a new file. The -i means there's one new file for each old file and the new files are given the same names as the old files (the old files are deleted once the command has run).
So far so good. But what happens if the grep doesn't return any filenames? In that case, your Perl command doesn't get any filenames and that would trigger the error that you are seeing.
So my (second) guess is that your grep command isn't doing what you want it to and is returning an empty list of filenames. Try running the grep command on its own and see what you get.

Bash script adding special characters to the end of any file I create

I am creating a bash script to create backups, however the bash scripts mkdir is naming the folder with some sort of special characters on the end. if I ls the directory the name show up with a ? on the end which I know is terminals way of showing unrecognized special characters.
How do I get my bash script to to create the folder without adding on this special unrecognized character to the end.
Any help is appreciated.
See script below:
#!/bin/bash
mkdir -p "/var/backups/Backup"
mysqldump -u user1 -ptest DB tbl1 > "/var/backups/Backup/tbl1.sql"
DAY=$(date +%Y%m%d%H%M%S)
zip -r /var/backups/bkup-$DAY.zip /var/backups/Backup
cat -A shows the following:
#!/bin/bash^M$
mkdir -p "/var/backups/Backup"^M$
mysqldump -u user1 -ptest DB tbl1 > "/var/backups/Backup/tbl1.sql"^M$
DAY=$(date +%Y%m%d%H%M%S)^M$
zip -r /var/backups/bkup-$DAY.zip /var/backups/Backup
the ^M (CR) characters in your cat -A output are the problem: the shell treats only LF as the "end of line" marker, and the preceding CR character becomes part of the previous word. only '/' and '\0' characters are forbidden in pathnames in POSIX(ish) systems.
you can fix your script with dos2unix or with
vim yourfile.sh
:set ff=unix
:wq

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

use of sed substitute in shell script doesn't work

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
$

Resources