sed 仅删除 sed '=' 命令提供的 \n

Lin*_*bie 7 pipe sed newlines text-formatting

我使用以下方法创建了一个文件:

printf 'this is \n not is \n is is \n this biz' > file2
Run Code Online (Sandbox Code Playgroud)

当我尝试删除所有 \n(newline) 时,它只会删除 sed 自己插入的数字的换行符

sed  '=' file2 | sed 'N; s/\n/ /' 
Run Code Online (Sandbox Code Playgroud)

输出是:

 1 this is 
 2  not is 
 3  is is 
 4  this biz
Run Code Online (Sandbox Code Playgroud)

而不是我所期望的:

1 this is  2  not is  3  is is  4  this biz
Run Code Online (Sandbox Code Playgroud)

我搞不清楚了。

Kus*_*nda 7

你的第二个sed脚本,

N
s/\n/ /
Run Code Online (Sandbox Code Playgroud)

不会以您期望的方式工作,因为它会读取一行,然后使用N命令插入的嵌入换行符将下一行附加到该行,然后用空格(和输出)替换该换行符。在读取之后的行时,前两行的结果将被丢弃。

相反,您将不得不使用保留空间:

H;            # append to hold space with a '\n' embedded
              # for the last line:
${
    x;        # swap in the hold space
    s/\n//;   # delete the first newline (from the H command on the very first line of input)
    y/\n/ /;  # replace all other newlines with spaces
    p;        # print result
}
Run Code Online (Sandbox Code Playgroud)

该脚本为每一行输入运行一次,在保持空间中收集数据,直到我们到达最后一行。在最后一行,我们处理收集到的数据并输出。

您可以使用以下命令运行它sed -n

$ sed '=' <file2 | sed -n 'H; ${ x; s/\n//; y/\n/ /; p; }'
1 this is  2  not is  3  is is  4  this biz
Run Code Online (Sandbox Code Playgroud)

(输出末尾没有换行符,因为输入末尾没有换行符)。

或者,通过显式循环,我们可以使用N. 这里的技巧是在我们准备好打印结果之前永远不要到达脚本的末尾。

:top;     # define label 'top'
N;        # append next line with a '\n' embedded
$!btop;   # if not at end, branch to 'top'
y/\n/ /;  # replace all newlines with spaces
          # (implicit print)
Run Code Online (Sandbox Code Playgroud)

这个脚本只运行(到最后)一次并管理数据本身的读取,而前一个脚本由内置读取循环提供数据sed(它替换了每行读取的模式空间,这是您的问题)。它使用模式空间而不是保持空间来收集数据并在读取最后一行时对其进行处理。

在命令行上:

$ sed '=' <file2 | sed ':top; N; $!btop; y/\n/ /'
Run Code Online (Sandbox Code Playgroud)

(与上面相同的输出)