我使用以下方法创建了一个文件:
printf 'this is \n not is \n is is \n this biz' > file2
当我尝试删除所有 \n(newline) 时,它只会删除 sed 自己插入的数字的换行符
sed '=' file2 | sed 'N; s/\n/ /'
输出是:
1 this is
2 not is
3 is is
4 this biz
而不是我所期望的:
1 this is 2 not is 3 is is 4 this biz
我搞不清楚了。
答案1
你的第二个sed
脚本,
N
s/\n/ /
不会按照您期望的方式工作,因为它将读取一行,然后将下一行附加到该行并使用命令插入的嵌入式换行符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
}
该脚本针对每行输入运行一次,收集保留空间中的数据,直到我们到达最后一行。在最后一行,我们处理收集到的数据并将其输出。
您可以使用以下命令运行它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
(输出末尾没有换行符,因为输入末尾没有换行符)。
或者,通过显式循环,我们可以使用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)
该脚本仅运行(到最后)一次,并管理数据本身的读取,而前一个脚本是通过内置读取循环提供数据的sed
(其中替换模式空间对于读取的每一行,这是您的问题)。它使用模式空间而不是保持空间来收集数据,并在读取最后一行时对其进行处理。
在命令行上:
$ sed '=' <file2 | sed ':top; N; $!btop; y/\n/ /'
(与上面相同的输出)
答案2
如果是GNU sed
,试试这个
$ sed -z 's/\n/ /g' file2
this is not is is is this biz
$
tr
做得同样好。
$ tr '\n' ' ' <file2
this is not is is is this biz
$
答案3
这从根本上来说是因为sed
是面向线路的。发生的情况是
- sed 将第一行加载
1
到模式空间中 - 该
N
命令加载下一行,并将其附加到模式空间,以 分隔\n
,给出1\nthis is
- 我们
\n
用空间来代替1 this is
我们就完成了;打印图案空间,然后对剩余的每行(成对)重复这些步骤。
答案4
尝试使用以下命令,效果很好
inputfile
this is
not is
is is
命令:
cat inputfile|sed "="| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"
输出
1 this is 2 not is 3 is is 4 this biz