I have a script that is appending new fields to an existing CSV, however ^M
characters are appearing at the end of the old lines so the new fields end up on a new row instead of the same one. How do I remove ^M
characters from a CSV file using Perl?

- 30,738
- 21
- 105
- 131

- 761
- 3
- 9
- 15
-
Use `binmode(STDIN, ":crlf")` or `PERLIO=:unix:crlf` (see [http://stackoverflow.com/a/21320709/424632]). – musiphil Jan 23 '14 at 22:35
11 Answers
Or a 1-liner:
perl -p -i -e 's/\r\n$/\n/g' file1.txt file2.txt ... filen.txt

- 2,079
- 14
- 15
-
3
-
On windows passing *.txt with this command does not work. It gives: Can't open *.txt: Invalid argument. Anyone? – mgouin Dec 10 '15 at 19:26
-
You found out you can also do this:
$line=~ tr/\015//d;
-
1not as readable as `\r` - anyone looking at that (or yourself in a year's time) would be glad of a comment stating what it does – plusplus Jun 21 '11 at 08:12
Slightly unrelated, but to remove ^M from the command line using Perl, do this:
perl -p -i -e "s/\r\n/\n/g" file.name

- 30,738
- 21
- 105
- 131

- 3,683
- 6
- 35
- 36
I prefer a more general solution that will work with either DOS or Unix input. Assuming the input is from STDIN:
while (defined(my $ln = <>))
{
chomp($ln);
chop($ln) if ($ln =~ m/\r$/);
# filter and write
}

- 173
- 1
- 8
This one liner replaces all the ^M characters:
dos2unix <file-name>
You can call this from inside Perl or directly on your Unix prompt.

- 30,738
- 21
- 105
- 131

- 31
- 1
To convert DOS style to UNIX style line endings:
for ($line in <FILEHANDLE>) {
$line =~ s/\r\n$/\n/;
}
Or, to remove UNIX and/or DOS style line endings:
for ($line in <FILEHANDLE>) {
$line =~ s/\r?\n$//;
}

- 21,335
- 15
- 77
- 102
This is what solved my problem. ^M is a carriage return, and it can be easily avoided in a Perl script.
while(<INPUTFILE>)
{
chomp;
chop($_) if ($_ =~ m/\r$/);
}

- 30,738
- 21
- 105
- 131

- 41
- 1
- 11
-
Does that remove ^M from a CSV file? Changing the input file? Does it create some output file that will not have them? – Peter Mortensen Dec 07 '17 at 00:23
Little script I have for that. A modification of it helped to filter out some other non-printable characters in cross-platform legacy files.
#!/usr/bin/perl
# run this as
# convert_dos2unix.pl < input_file > output_file
undef $/;
$_ = <>;
s/\r//ge;
print;
perl command to convert dos line ending to unix line ending with backup of the original file:
perl -pi.bak -e 's/\r\n/\n/g' filename
This command generates filename with unix line ending and leaves the original file as filename.bak.

- 5,753
- 72
- 57
- 129
In vi hit :
.
Then s/Control-VControl-M//g
.
Control-V
Control-M
are obviously those keys. Don't spell it out.

- 30,738
- 21
- 105
- 131
-
1It's a bad idea to include non-printing characters like carriage return verbatim in source code like this. Far better to use the \r escape that is (a) easy to see and (b) won't get lost if the source is reformatted. – Denis Howe Dec 02 '15 at 17:16