首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sed:如何将CR和/或LF替换为"\r“"\n",以便任何文件都在一行中

sed:如何将CR和/或LF替换为"\r“"\n",以便任何文件都在一行中
EN

Stack Overflow用户
提问于 2011-03-24 16:12:54
回答 4查看 31.6K关注 0票数 0

我有这样的文件

aaa

bbb

ccc

我需要他们把他们转到aaa\r\nbbb\r\nccc

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

问题是,sed在行尾添加了\n,但保持了行之间的分隔。我怎么才能修好它?

EN

回答 4

Stack Overflow用户

发布于 2011-03-24 16:23:40

这两个命令一起执行您想做的事情:

代码语言:javascript
运行
复制
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?

票数 2
EN

Stack Overflow用户

发布于 2011-03-24 16:18:01

在sed中合并行是可能的,但就我个人而言,我认为需要更改行,这意味着是时候放弃sed,转而使用更强大的语言了。您需要的是一行perl:

代码语言:javascript
运行
复制
perl -e 'undef $/; while (<>) { s/\n/\\n/g; s/\r/\\r/g; print $_, "\n" }'

或者12行python:

代码语言:javascript
运行
复制
#! /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,所以还需要大量的代码:

代码语言:javascript
运行
复制
#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;
 }
票数 1
EN

Stack Overflow用户

发布于 2011-03-24 17:39:31

代码语言:javascript
运行
复制
tr -s '\r' '\n' <file | unix2dos

编辑(有人指出,上面的内容完全遗漏了要点!./.)

代码语言:javascript
运行
复制
tr -s '\r' '\n' <file | perl -pe 's/\s+$/\\r\\n/'

tr消除空行和dos行结束。管道意味着两个过程

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5422162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档