Way to remove newline (^M) from variables only, not from file
^M
is a carriage return (CR), which can be specified as \r
for tr
or within $'…'
. \n
specifies a line feed (LF), which is ^J
. A Unix line ending is LF, and a Windows line separator is the two-character sequence CR-LF, so Windows text files viewed under a Unix system such as Linux or macOS look like they have ^M
at the end of each line except on the last line which is missing its final newline.
You can remove carriage returns from a file with tr
with
tr -d '\r' <somefile.txt >somefile.txt.new && mv somefile.txt.new somefile.txt
or more simply with dos2unix
.
To avoid modifying the files, you can check each line when you read it and strip CR at the end of a line. For example, if you're using read
to parse tab-separated values, then strip CR at the end of the last field. The parameter expansion ${VAR%$'\r'}
yields the value of VAR
minus a trailing CR, and yields the value of VAR
if it doesn't end with CR.
while IFS=$'\t' read -r -a line
do
line[$((${#line[@]}-1))]="${line[$((${#line[@]}-1))]%$'\r'}"
Type1="${line[0]}"
Type2="${line[1]}"
done < "$TXTFILE"
Here is the simplest way to fix your script, simply add "carriage return" as a internal field separator for the read command:
while IFS=$'\t\r' read -r -a line do Type1="${line[0]}" Type2="${line[1]}" done < $TXTFILE
Use (for short strings):
${var//$'\015'}
Example:
$ var=$'This is a test of a CR (\r) character'
$ echo "${var//$'\r'}"
This is a test of a CR () character
For longer strings you may need sed or awk.