If your file uses mixed line breaks, i. e. \r\n
and \r
, you can use this sed
script (this is an all-in-one solution and of course, you can also use it if your file merely has \r\n
or \r
line breaks):
sed -i[SUFFIX] ':read; N; $!b read; s/\r\n/\n/g; s/\r/\n/g' file
-i
tells sed
to replace your file with the result of the script,
and if you supply a SUFFIX
, a backup will be created with that suffix.
You also may omit -i
and redirect the output to an arbitrary file.
How the script works:
Special commands:
N
: Adds a newline to the pattern space, then appends the next line of input (with any trailing \n
removed) to the pattern space.
$!
: Don't execute the following command on the last line.
b
: Branches unconditionally to the specified label.
So when the cycle starts (we have just one cycle here), sed
reads the first line of input, removes any trailing \n
and places it in the pattern space, then it processes the script:
N
adds a newline to the pattern space, then appends the next line of input (with any trailing \n
removed) to the pattern space.
This is repeated until the last line is reached, then the substitutions operate on the pattern space, which contains the whole file as a single line, which is the reason why we need the g
flag for the substitutions.
The first substitution replaces each \r\n
with \n
.
After this, the remaining ("lonesome") \r
s are replaced with \n
.
Why do we need the N
loop?
Since sed 's/<regexp>/<replacement>/[flags]' file
reads a line from the file, performs the substitution on it, prints the result, reads the next line and so on, \n
cannot be used within the <regexp>
part.
But if we have the whole file as a single line in the pattern space, we will be able to use \n
within the <regexp>
part, and this is necessary to distinguish between the sequence \r\n
and "lonesome" \r
s.
Example:
$ sudo file /var/log/apt/term.log
/var/log/apt/term.log: UTF-8 Unicode text, with CRLF, CR, LF line terminators, with escape sequences, with overstriking
$ sudo sed -i.bak ':read; N; $!b read; s/\r\n/\n/g; s/\r/\n/g' /var/log/apt/term.log
$ sudo file /var/log/apt/term.log
/var/log/apt/term.log: UTF-8 Unicode text, with escape sequences, with overstriking
help digraph-table
.