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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5422162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:13:08  来源:igfitidea点击:

sed: how to replace CR and/or LF with "\r" "\n", so any file will be in one line

windowsmacosunixsed

提问by 999

I have files like

我有类似的文件

aaa

bbb

ccc

啊啊啊

bbb

抄送

I need them to sed into aaa\r\nbbb\r\nccc

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

It should work either for unix and windows replacing them with \ror \r\naccordingly

它应该适用于 unix 和 windows 替换它们\r\r\n相应地

The problem is that sedadds \nat the end of line but keeps lines separated. How can I fix it?

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

回答by bdk

These two commands together should do what you want:

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

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

Pass your input file through both to get the output you want. Theres probably a way to combine them into a single expression.

通过两者传递您的输入文件以获得您想要的输出。可能有一种方法可以将它们组合成一个表达式。

Stolen and Modified from this question:

从这个问题被盗和修改:

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

如何使用 sed 替换换行符 (\n)?

回答by bobbogo

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

EDIT(it's been pointed out that the above misses the point entirely! ?///?)

编辑(有人指出上述内容完全没有抓住重点!?///?)

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

The trgets rid of empty lines and dos line endings. The pipe means two processes—good on modern hardware.

tr出手的空行和DOS行结束。管道意味着两个进程——在现代硬件上很好。

回答by zwol

It's possible to merge lines in sed, but personally, I consider needing to change line breaks a sign that it's time to give up on sed and use a more powerful language instead. What you want is one line of perl:

可以在 sed 中合并行,但就个人而言,我认为需要更改换行符表明是时候放弃 sed 并改用更强大的语言了。你想要的是一行 perl:

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

or 12 lines of python:

或 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")

or 10 lines of C to do the job, but then a whole bunch more because you have to process argvyourself:

或者 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;
 }

回答by glenn Hymanman

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

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