我有一个名为 file1 的文件,其中包含以下内容:
The answer t
o your question
A conclusive a
nswer isn’t al
ways possible.
When in doubt, ask pe
ople to cite their so
urces, or to explain
Even if we don’t agre
e with you, or tell y
ou.
我想将 file1 转换为 file2 。后者应如下所示:
The answer to your question
A conclusive answer isn’t always possible.
When in doubt, ask people to cite their sources, or to explain
Even if we don’t agree with you, or tell you.
如果我只是执行cat file1 | tr -d "\n" > file2"
,则会删除所有换行符字符。何时只删除使用tr(1)
实用程序在非空行上的换行符字符?
答案 0 :(得分:9)
perl -00 -lpe 'tr/\n//d'
-00
是Perl的“段落”模式,用一个或多个空行作为分隔符读取输入。 -l
将系统换行符附加到print命令,因此删除输入中的所有换行符是安全的。
答案 1 :(得分:3)
tr
无法执行此操作,但sed
可以轻松
sed -ne '$!H;/^$/{x;s/\n//g;G;p;d;}' file1 > file2
这会找到非空行并保留它们。然后,在空行上,它从保留的数据中删除换行符并打印结果,后跟换行符。删除保留的数据并重复该过程。
编辑:
Per @ potong的评论,这是一个版本,在文件的末尾不需要额外的空行。
sed -ne 'H;/^$/{x;s/\n//g;G;p;};${x;s/\n//g;x;g;p;}' file1 > file2
答案 2 :(得分:2)
如果您认识的某个角色没有出现在您的输入中,您可以执行以下操作:
# Assume that the input doesn't contain the '|' character at all
tr '\n' '|' < file1 | sed 's/\([^|]\)|\([^|]\)/\1\2/g' | tr '|' '\n' > file2
用替换字符|
替换所有换行符; sed
然后删除在其他角色之前和之后的所有|
实例;最后,它用换行符替换|
。
答案 3 :(得分:2)
这可能对您有用:
# sed '1{h;d};H;${x;s/\([^\n]\)\n\([^\n]\)/\1\2/g;p};d' file
The answer to your question
A conclusive answer isn't always possible.
When in doubt, ask people to cite their sources, or to explain
Even if we don't agree with you, or tell you.
答案 4 :(得分:2)
file1
中的换行符分为四类:
通过阅读整个输入(-000
选项)删除第一个类,并在每个地方替换一个换行符,我们看到一对(s/\n\n/\n/g
)让我们
$ perl -000 -pe 's/\n\n/\n/g' file1 The answer t o your question A conclusive a nswer isn’t al ways possible. When in doubt, ask pe ople to cite their so urces, or to explain Even if we don’t agre e with you, or tell y ou.
这不是我们想要的,因为第一类换行应终止file2
中的行。
我们可能会尝试聪明并使用负面后视来删除前面有其他换行符(第二类)的换行符,但输出与前一种情况无法区分,这是有道理的,因为这次我们删除了后者而不是前者在每个相邻的新线中。
$ perl -000 -pe 's/(?<=\n)\n//g' file1 The answer t o your question A conclusive a nswer isn’t al ways possible. When in doubt, ask pe ople to cite their so urces, or to explain Even if we don’t agre e with you, or tell y ou.
即便如此,这仍然不是我们想要的,因为其他新行的前面的成为file2
中的空行。
很明显,我们希望在file1
结束时继续使用换行符。
我们想要的是一个只删除第四个类的程序:每个换行符之前没有另一个换行符,后面跟着另一个换行符和逻辑输入结束符。
使用Perl's look-around assertions,规范很简单,虽然外观可能有点令人生畏。 “没有换行符”是负面的后瞻(?<!\n)
。使用否定前瞻(?!...)
我们不希望看到另一个换行符或(|
)输入的结尾($
)。
把它们放在一起我们得到了
$ perl -000 -pe 's/(?<!\n)\n(?!\n|$)//g' file1 The answer to your question A conclusive answer isn’t always possible. When in doubt, ask people to cite their sources, or to explain Even if we don’t agree with you, or tell you.
最后,要创建file2
,请重定向标准输出。
perl -000 -pe 's/(?<!\n)\n(?!\n|$)//g' file1 >file2
答案 5 :(得分:0)
你不能单独使用tr
。 tr
非常方便,但严格来说是char-by-char过滤器,没有前瞻或后视。
您可以使用sed
获取示例输出,但这真的很痛苦(我想!)。 编辑(sed master @Sorpigal证明我错了!)
以下是awk
/home/shellter:>cat <<-EOS \
| awk 'BEGIN{RS="\n\n"}; { gsub("\n", "", $0) ;printf("%s %s", $0, "\n\n") }'
The answer t
o your question
A conclusive a
nswer isn’t al
ways possible.
When in doubt, ask pe
ople to cite their so
urces, or to explain
Even if we don’t agre
e with you, or tell y
ou.
EOS
# output
The answer to your question
A conclusive answer isnt always possible.
When in doubt, ask people to cite their sources, or to explain
Even if we dont agree with you, or tell you.
很奇怪,它显示为三倍间距,但它实际上是间隔的。
Awk有为每个文件填充的预定义变量,以及它读取的每行文本,即
RS = RecordSeperator -- normally a line of data, but a configurable value, that when set
to '\n\n' means a blank line, or a typical separation on a paragraph
$0 = complete line of text (as defined by the internal variables RS (RecordSeparator)
In this problem, it is each paragraph of data, viewed though
as a record.
$1 = first field in text (as defined by the internal variables FS (FieldSeparator)
which defaults to (possibly multiple) space chars OR tab char
a line with 2 connected spaces chars and 1 tab char has 3 fields)
NF = Number(of)Fields in current line of data (again fields defined by value of FS as
described above)
(there are many others, besides, $0, $n, $NF, $FS, $RS).
你可以通过在示例代码中使用变量来编程增加$ 1,$ 2,$ 3等值,例如$ i(i是一个介于2和NF之间的数字的变量。前导'$' 说给我字段i的价值(即2美元,3美元,4美元......)
我希望这会有所帮助。