sed:如何用“\ r”“\ n”替换CR和/或LF,因此任何文件都在一行中

时间:2011-03-24 16:12:55

标签: windows macos unix sed

我有像

这样的文件
  

AAA

     

BBB

     

CCC

我需要他们进入aaa\r\nbbb\r\nccc

它应该适用于unix和windows,因此用\r\r\n替换它们

问题是sed在行尾添加\n但保持行分隔。我该如何解决?

4 个答案:

答案 0 :(得分:2)

这两个命令一起应该做你想做的事:

sed ':a;N;$!ba;s/\r/\\r/g'
sed ':a;N;$!ba;s/\n/\\n/g'

将输入文件传递到两者以获得所需的输出。这可能是将它们组合成单个表达式的一种方式。

从这个问题中被盗和修改:

How can I replace a newline (\n) using sed?

答案 1 :(得分:1)

可以合并sed中的行,但就个人而言,我认为需要更改换行符,这是放弃sed并使用更强大的语言的标志。你想要的是一行perl:

perl -e 'undef $/; while (<>) { s/\n/\\n/g; s/\r/\\r/g; print $_, "\n" }'

或12行python:

#! /usr/bin/python
import fileinput
from sys import stdout
first = True
for line in fileinput.input(mode="rb"):
    if fileinput.isfirstline() and not first:
        stdout.write("\n")
    if line.endswith("\r\n"): stdout.write(line[:-2] + "\\r\\n")
    elif line.endswith("\n"): stdout.write(line[:-1] + "\\n")
    elif line.endswith("\r"): stdout.write(line[:-1] + "\\r")
    first = False
if not first: stdout.write("\n")

或10行C来完成这项工作,但后来又增加了很多,因为你必须自己处理argv

#include <stdio.h>

void process_one(FILE *fp)
{
    int c;
    while ((c = getc(fp)) != EOF)
        if (c == '\n') fputs("\\n", stdout);
        else if (c == '\r') fputs("\\r", stdout);
        else putchar(c);
    fclose(fp);
    putchar('\n');
}

int main(int argc, char **argv)
{
    FILE *cur;
    int i, consumed_stdin = 0, rv = 0;
    if (argc == 1) /* no arguments */
    {
        process_one(stdin);
        return 0;
    }

    for (i = 1; i < argc; i++)
    {
        if (argc[i][0] == '-' && argc[i][1] == 0)
        {
            if (consumed_stdin)
            {
                fputs("cannot read stdin twice\n", stderr);
                rv = 1;
                continue;
            }
            cur = stdin;
            consumed_stdin = 1;
        }
        else
        {
            cur = fopen(ac[i], "rb");
            if (!cur)
            {
                perror(ac[i]);
                rv = 1;
                continue;
            }
        }
        process_one(cur);
     }
     return rv;
 }

答案 2 :(得分:1)

tr -s '\r' '\n' <file | unix2dos

编辑(有人指出上述内容完全忽略了这一点!•///•)

tr -s '\r' '\n' <file | perl -pe 's/\s+$/\\r\\n/'

tr摆脱了空行和dos行结尾。管道意味着两个过程 - 在现代硬件上很好。

答案 3 :(得分:0)

awk '{printf("%s\\r\\n",$0)} END {print ""}' file