Bash – does this echo call overwrite existing text

bashshell-script

Consider the following CSV file:

jdbc.driverClassName,oracle.jdbc.driver.OracleDriver

jdbc.username,kshitiz

It has to be transformed into:

-Djdbc.driverClassName=oracle.jdbc.driver.OracleDriver \

-Djdbc.username=kshitiz \

Given the following bash snippet:

while read l; do
    IFS=',' read -ra arr <<< "$l"
    echo '-D'${arr[0]}'='${arr[1]}' \'
done <properties.txt

Bash prints:

\jdbc.driverClassName=oracle.jdbc.driver.OracleDriver 

\jdbc.username=kshitiz

What's going on here?

Best Answer

 \jdbc.driverClassName=oracle.jdbc.driver.OracleDriver

What your script has actually output is

  1. -Djdbc.driverClassName=oracle.jdbc.driver.OracleDriver
  2. a carriage return
  3.  \ (note the space)
  4. a newline

Why has your script printed a carriage return? Because your input file does not have Unix-convention newlines, but has CRLFs instead, and the carriage return at the end of each line has been considered part of the second array variable.

Why is whitespace like a carriage return being appended to a variable by read? Because you changed IFS.

Some words to the wise:

  • Use printf, not echoespecially, as here, when you are passing echo things that look like command-line options and things with backslashes in.
  • Diagnose these sorts of problems by passing the output through hexdump -C, cat -v, or od -t c -t x1.
  • If you don't have dos2unix, it is easy to do the equivalent with tr, sed, or perl.
Related Question