Dan
Dan

Reputation: 39

Perl - remove carriage return and append next line

What if I have a record in a otherwise good file that had a carriage return in it.

Ex:

1,2,3,4,5 ^M
,6,7,8,9,10

and I wanted to make it

1,2,3,4,5,6,7,8,9,10

Upvotes: 3

Views: 15581

Answers (6)

kriss
kriss

Reputation: 24177

Every line is ended with some terminator sequence, either

  • CRLF (\r\n = 13, 10) on Windows/DOS
  • CR (\n = 13) on Unix
  • LF (\r = 10) on MacOS

If some lines are OK, you should say from wich system the file comes or on wich system the perl script is executed, or the risk is to remove every end of line and merge all of your program lines...

As ^M is the CR character, if you see such a character at the end of a line and nothing special on other lines, you are probably using some kind of Unix (Linux ?) and some copy/paste has polluted one line with an additional \r at the end of line.

if this is the case :

perl -pi -e 's/\r\n$//g' filetomodify

will do the trick and merge only the line containing both CR and LF with the next line, leaving the other lines untounhed.

Upvotes: 0

vol7ron
vol7ron

Reputation: 42109

More Information Needed


More information is needed about the underlying data and what your definition of carriage return is. Is the data in Linux or Windows? Really, do you mean carriage return/line feed, or just line feed?


Some Options:

  • $text =~ tr/\r//; → this is the fastest method to weed out carriage returns
  • $text =~ tr/\n//; → this is the fastest method to change newlines
  • $test =~ s/\n//s; → this is probably what you're looking for, which makes the text appear as one line and removes the internal \n

Upvotes: -1

Greg Bacon
Greg Bacon

Reputation: 139521

Say we have a file that contains a ctrl-M (aka \r on some platforms):

$ cat input 
1,2,3
4,5,6
,7,8,9
10,11,12

This is explicit with od:

$ od -c input 
0000000   1   ,   2   ,   3  \n   4   ,   5   ,   6  \r  \n   ,   7   ,
0000020   8   ,   9  \n   1   0   ,   1   1   ,   1   2  \n
0000035

Remove each offending character and join its line with the next by running

$ perl -pe 's/\cM\cJ?//g' input 
1,2,3
4,5,6,7,8,9
10,11,12

or redirect to a new file with

$ perl -pe 's/\cM\cJ?//g' input >updated-input

or overwrite it in place (plus a backup in input.bak) with

$ perl -i.bak -pe 's/\cM\cJ?//g' input

Making the \cJ optional handles the case when a file ends with ctrl-M but not ctrl-J.

Upvotes: 1

runrig
runrig

Reputation: 6524

Assuming the carriage return is right before the line feed:

perl -pi.bak -e 's/\r\n//' your_file_name

This will join only lines with a carriage return at the end of the line to the next line.

Upvotes: 0

Ether
Ether

Reputation: 53976

In general, if you have a string with a stray newline at the end that you want to get rid of, you can use chomp on it (note that you can pass it an lvalue, so wrapping it around an assignment is legal):

my $string = $string2 = "blah\n";
chomp $string;

# this works too:
chomp(my $string3 = $string2);

Note that if the string has a trailing "\r\n", chomp won't take the \r as well, unless you modify $/.

So if all of that is too complicated, and you need to remove all occurrences of \n, \r\n and \r (maybe you're processing lines from a variety of architectures all at once?), you can fall back to good old tr:

$string =~ tr/\r\n//d;

Upvotes: 3

plor
plor

Reputation: 282

s/[\r\n]//g

Only do this if you want to combine a line with the next.

Upvotes: 0

Related Questions