Using SED in a shell script - shell

I have two issues that I am seeking help with. I am using Cygwin and a Unix newbie.
1) I have a shell script that executes SED command. In my script called master.sh, I have the following
sed -nrf remove.sed < code.tp4 > code.tp5
remove.sed has one line
/ INCLUDE /d
When I execute the script via the following command
bash master.sh
I get the following error
master.sh: line 12: $'\r':command not found
I have no clue on what is throwing this error.
2) My 2nd issue is that the output file "code.tp5" ends up "code.tp5?". However, using Windows explorer, the question mark appears to be
unprintable characters. The most confusing part of this is that I get no errors when I execute this via the command prompt. Any assistance would be appreciated.

You could try:
sed -nr s/\r//;/ INCLUDE /d' < code.tp4 > code.tp5; sed 's/$/\r$/' code.tp5
The command 's' is for substitution. '\r' carriage return. So s/\r// will replace carriage return to nothing. After that you will remove the lines that contains the pattern '/ INCLUDE /d'. And with this: sed 's/$/\r$/' code.tp5 finally you will add again the carriage return so will became again a DOS text file ($ means end of line on a regular expression) . (Unix line endings are only new line, and DOS cas carriage return and newline).

Related

If-then-else syntax in tcsh

I'm trying to write a simple script in tcsh (version 6.12.00 (Astron) 2002-07-23), but I am getting tripped up by the if-then-else syntax. I am very new to script writing.
This script works:
#!/bin/tcsh -f
if (1) echo "I disagree"
However, this one does not:
#!/bin/tcsh -f
if ( 1 ) then
echo "I disagree"
else
echo "I agree"
endif
For one thing, this code, when run, echoes both statements. It seems to me it should never see the else. For another, the output also intersperses those echoes with three iterations of ": Command not found."
Edited to add: here is the verbatim output:
: Command not found.
I disagree
: Command not found.
I agree
: Command not found.
I know that the standard advice is to use another shell instead, but I am not really in a position to do that (new job, new colleagues, everyone else uses tcsh, want my scripts to be portable).
When I copy-and-paste your script and run it on my system, it correctly prints I disagree.
When I change the line endings to Windows-style, I get:
: Command not found.
I disagree
: Command not found.
I agree
: Command not found.
So, your script very likely has Windows-style line endings. Fix the line endings, and it should work. The dos2unix command is one way to do that (man dos2unix first; unlike most UNIX text-processing commands, it replaces its input file.)
The problem is that tcsh doesn't recognize ^M ('\r') as an end-of-line character. It sees the then^M at the end of the line as a single command, and prints an error message then^M: Command not found. The ^M causes the cursor to return to the beginning of the line, and the rest of the message overwrite the then.

: command not foundop/dominio.sh: line 2:

I'm writing shell scripting for Mac.
Here's my script:
echo "Bienvenido";
/Applications/sdk/platform-tools/adb devices;
sudo /Applications/sdk/platform-tools/adb shell input text 'sp.soporte#gmail.com';
It realize the correct operation, but here is the output :
$ /Users/julien/Desktop/dominio.sh
Bienvenido
: command not foundop/dominio.sh: line 1:
List of devices attached
4790057be1803096 device
: command not foundop/dominio.sh: line 2:
: command not foundop/dominio.sh: line 3:
julien$
If I erase the ; it's not working any more. How should I do????
I think you have Windows-style line endings in your script.
Unix-like systems, including MacOS, use a single LF character to terminate a line; Windows uses a CR-LF pair.
A Windows-style text file looks, on a Unix-like system, like ordinary text with an extra CR character at the end of each line.
Since you have a semicolon at the end of each line, this line:
echo "Bienvenido";
appears to the shell as two commands: echo "Bienvenido" and the CR character (which could actually be a command name if it existed). Note that the echo command was executed.
The shell prints an error message, something like:
/path/to/script: 1: CR: command not found
except that it prints the actual CR (carriage return) character, which moves the cursor to the beginning of the current line, overwriting part of the error message.
Translate your script to use Unix-style line endings. You can use dos2unix for this if you have it. (Read the man page; unlike most filter programs, it overwrites its input file by default.)
Incidentally, you don't need a semicolon on the end of each line of a shell script. Semicolons are needed only when you have multiple commands on one line.
Also, you should probably have a "shebang" as the first line of your script, either #!/bin/sh or #!/bin/bash (use the latter if your script uses bash-specific features).

Bash for loop error

I am trying out a simple bash script using for loop, and kept getting the following error:
'/test.sh: line 2: syntax error near unexpected token `do
'/test.sh: line 2: `do
The following is the code that is being used...
for animal in dog cat elephant
do
echo "There are ${animal}s.... "
done
However, when I tried on other machines.. it is working no problem.
Please help.
Your test.sh script has Windows-style line endings. The shell sees each \r\n sequence as a \r character at the end of the line.
The shell is seeing do\r rather than do. Since \r sends the cursor to the beginning of the line, that's why you're seeing the quotation mark at the beginning of the line. Try
./test.sh 2>&1 | cat -A
to see what's actually in the error message.
Filter your test.sh script through something like dos2unix to correct the line endings. (Be sure to read the man page first; dos2unix, unlike most text filters, overwrites its input file.)
This is a common problem on Cygwin. Did you use a Windows editor to create the script?

Redirecting standard output to new file adds strange character to end of filename in cygwin

I'm having trouble with a shell script in Cygwin. The specific command that's causing the problem is this:
sed -e "s/6.0.[0123456789]\{1,\}/6.0.${REV}/g" "path/to/file/config.xml" > "path/to/file/config.xml.tmp"
The problem is that the file is being created with a strange character at the end, so instead of being named config.xml.tmp, it's named "config.xml.tmp". From the "ls" command and from the windows command prompt, it looks like "config.xml.tmp?"
If I run the sed command just from the shell, the file named correctly, and the script works fine in Linux.
Any idea what could be wrong? Thanks!
My guess is that your script file doesn't have UNIX line endings. The \r character in the windows line ending is what's getting added to the end of your filename. You can check with od or hexdump to see if that's the problem.

echo printing variables on single line

I have two variables:
export portNumber=8888^M
export loginIP_BASE=10.1.172.2^M
I'm trying to print them both on a single line separated by a colon ':'. It should look like "10.1.172.2:8888"
echo -n 'Login IP:'
echo -n $loginIP_BASE
echo -n ':'
echo $portNumber
but it it prints this instead:
:8888 IP:10.1.172.2
Why is it doing that? How can I get it to do what I want?
Also, the variables are preexisting from another file, so I did not write them myself. What does the "^M" do?
In Windows a tipical new line is \r\n (in *nix systems is just \n).
\r is carriage return.
\n is new line.
^M is \r, so after writing $loginIP_BASE you are at position 0 of the actual line.
If you want to remove all those ^M you can do it in vim o with sed using:
sed s/{ctrl+v}{ctrl+m}// file > new_file
({Ctrl+v} means press ctrl and then v)
The file has been transferred from Windows in binary mode, and still has carriage return characters at the ends of the lines.
They are your ^M symbols, and they are causing the text position to return to the start of the line when the values are displayed - the carriage return at the end of the first value makes the second value display at the start of the line again, overwriting part of the first value.
The right fix is to transfer the file from Windows using text mode transfer, or to run dos2unix on the file after you've transferred it. (Or if the file isn't going to be transferred from Windows again, just delete the ^M characters!)
Use dos2unix command:
dos2unix filename
One more trick to remove Ctrl+M in vi editor:
:%s/^V^M//g

Resources