Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BASH: Strip new-line character from string (read line)

I bumped into the following problem: I'm writing a Linux bash script which does the following:

  • Read line from file
  • Strip the \n character from the end of the line just read
  • Execute the command that's in there

Example: commands.txt

ls
ls -l
ls -ltra
ps as

The execution of the bash file should get the first line, and execute it, but while the \n present, the shell just outputs "command not found: ls" That part of the script looks like this

 read line

        if [ -n "$line" ]; then #if not empty line

                #myline=`echo -n $line | tr -d '\n'`
                #myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'`

                myline=`echo -n $line | tr -d "\n"`
                $myline  #execute it

                cat $fname | tail -n+2 > $fname.txt
                mv $fname.txt $fname
        fi

Commented you have the things I tried before asking SO. Any solutions? I'm smashing my brains for the last couple of hours over this...

like image 500
Bogdan Constantinescu Avatar asked Sep 22 '09 10:09

Bogdan Constantinescu


People also ask

How do you escape a new line in Shell?

Escape character ( \ ) can be used to escape end of line, e.g. however, isn't end of line (new line) represented by \n which has two characters.

How do I remove special characters from a string in Linux?

The tr command (short for translate) is used to translate, squeeze, and delete characters from a string. You can also use tr to remove characters from a string. For demonstration purposes, we will use a sample string and then pipe it to the tr command.


2 Answers

I always like perl -ne 'chomp and print' , for trimming newlines. Nice and easy to remember.

e.g. ls -l | perl -ne 'chomp and print'

However

I don't think that is your problem here though. Although I'm not sure I understand how you're passing the commands in the file through to the 'read' in your shell script.

With a test script of my own like this (test.sh)

read line
if [ -n "$line" ]; then
  $line
fi

and a sample input file like this (test.cmds)

ls 
ls -l
ls -ltra

If I run it like this ./test.sh < test.cmds, I see the expected result, which is to run the first command 'ls' on the current working directory.

Perhaps your input file has additional non-printable characters in it ?

mine looks like this

od -c test.cmds 
0000000    l   s      \n   l   s       -   l  \n   l   s       -   l   t
0000020    r   a  \n                                                    
0000023

From your comments below, I suspect you may have carriage returns ( "\r" ) in your input file, which is not the same thing as a newline. Is the input file originally in DOS format ? If so, then you need to convert the 2 byte DOS line ending "\r\n" to the single byte UNIX one, "\n" to achieve the expected results.

You should be able to do this by swapping the "\n" for "\r" in any of your commented out lines.

like image 195
cms Avatar answered Sep 21 '22 13:09

cms


Someone already wrote a program which executes shell commands: sh file

If you really only want to execute the first line of a file: head -n 1 file |sh

If your problem is carriage-returns: tr -d '\r' <file |sh

like image 36
Mark Edgar Avatar answered Sep 22 '22 13:09

Mark Edgar