sed/awk-根据条件删除换行符
我有以下案文:sed/awk-根据条件删除换行符,awk,sed,newline,Awk,Sed,Newline,我有以下案文: pane 0 1 :title 1 :* 1 :/home/user 0 app1name : app1 -some -stuff pane 0 1 :title 1 :* 2 :/home/user 0 app2name : pane 0 1 :title 1 :* 3 :/home/user 1 app3name : app3 window 0 1 1 :
pane 0 1 :title 1 :* 1 :/home/user 0 app1name :
app1 -some -stuff
pane 0 1 :title 1 :* 2 :/home/user 0 app2name :
pane 0 1 :title 1 :* 3 :/home/user 1 app3name :
app3
window 0 1 1 :* somelongstuff
state 0
我试图达到的目的是在结束后删除换行符:
,但仅当以下行不是以窗格\t
或窗口\t
因此,最终输出应如下所示:
pane 0 1 :title 1 :* 1 :/home/user 0 app1name :app1 -some -stuff
pane 0 1 :title 1 :* 2 :/home/user 0 app2name :
pane 0 1 :title 1 :* 3 :/home/user 1 app3name :app3
window 0 1 1 :* somelongstuff
state 0
我尝试了几个sed和awk,比如
sed'/\npane\t/n/窗口\t/n;Ns/:\n/:/g'
或awk'{ORS=(/pane\t/?“”:RS)}1'
但它们都会以某种方式失败
有人能帮我吗?Perl来救我吧
perl -pe 'print "\n" if $chomped && /^(pane|window)\t/; $chomped = /:$/ ? chomp : 0' -- file
逐行读取输入,处理后打印每一行-p
- 删除尾随的换行符(如果存在)。它还返回删除的字符数
如果冒号是行中的最后一个字符,则匹配/:$/
是三元运算符。如果条件为true,即如果冒号是行上的最后一个字符,我们将删除新行(如果存在),并将?:
变量设置为1,否则将设置为0$chomped
- 读取一行时,
变量告诉我们是否从前一行删除了换行符。如果是,但当前行以$chomped
或窗格
开头,然后是窗口
,我们将换行插入后面\t
perl -pe 'print "\n" if $chomped && /^(pane|window)\t/; $chomped = /:$/ ? chomp : 0' -- file
逐行读取输入,处理后打印每一行-p
- 删除尾随的换行符(如果存在)。它还返回删除的字符数
如果冒号是行中的最后一个字符,则匹配/:$/
是三元运算符。如果条件为true,即如果冒号是行上的最后一个字符,我们将删除新行(如果存在),并将?:
变量设置为1,否则将设置为0$chomped
- 读取一行时,
变量告诉我们是否从前一行删除了换行符。如果是,但当前行以$chomped
或窗格
开头,然后是窗口
,我们将换行插入后面\t
sed
并不真正适合此任务。你必须摆弄赛德的控制空间才能让它工作。在这一点上,更容易切换到另一个工具
下面是一个perl
脚本
perl -np0 -e 's/:\n(?!pane\t|window\t)/:/g'
在管道中使用它或将文件名作为参数传递。
sed
不适合此任务。你必须摆弄赛德的控制空间才能让它工作。在这一点上,更容易切换到另一个工具
下面是一个perl
脚本
perl -np0 -e 's/:\n(?!pane\t|window\t)/:/g'
在管道中使用它或将文件名作为参数传递。在每个UNIX框的任何shell中使用任何awk:
$ awk 'NR>1{printf "%s%s", p, ((p ~ /:$/) && !/^(pane|window)\t/ ? "" : ORS)} {p=$0} END{print p}' file
pane 0 1 :title 1 :* 1 :/home/user 0 app1name :app1 -some -stuff
pane 0 1 :title 1 :* 2 :/home/user 0 app2name :
pane 0 1 :title 1 :* 3 :/home/user 1 app3name :app3
window 0 1 1 :* somelongstuff
state 0
在每个UNIX设备上的任何shell中使用任何awk:
$ awk 'NR>1{printf "%s%s", p, ((p ~ /:$/) && !/^(pane|window)\t/ ? "" : ORS)} {p=$0} END{print p}' file
pane 0 1 :title 1 :* 1 :/home/user 0 app1name :app1 -some -stuff
pane 0 1 :title 1 :* 2 :/home/user 0 app2name :
pane 0 1 :title 1 :* 3 :/home/user 1 app3name :app3
window 0 1 1 :* somelongstuff
state 0
这可能适用于您(GNU-sed):
在整个文件长度上打开一个两行窗口。如果第一行以:
结尾,第二行不是以窗格
或窗口
开头,请删除换行符。打印/删除第一行并重复
或者,反思一下:
sed 'N;/:\n\(window\|pane\)/!s/:\n/:/;P;D' file
这可能适用于您(GNU-sed):
在整个文件长度上打开一个两行窗口。如果第一行以:
结尾,第二行不是以窗格
或窗口
开头,请删除换行符。打印/删除第一行并重复
或者,反思一下:
sed 'N;/:\n\(window\|pane\)/!s/:\n/:/;P;D' file
将这些努力张贴到question@Inian应要求,我在服务器上添加了两个(失败的)尝试来阻止这些努力question@Inian按照要求,我添加了一些(失败的)尝试,因为这个SED命令没有考虑<代码>:<代码>可能删除<代码> \n>代码>我应该注意排除“代码>状态< /代码>(最后一行关键字)。并且可能在窗格、窗口和状态之后添加
\t
,以更好地确保它不会在不应该删除的时候删除\n
。提出了以下建议:sed'n;/\n\(窗格\t\\窗口\t\\状态\t\)/s/\n//p;d’文件< /代码>,它似乎起作用。我是正确的吗?因为这个SED命令没有考虑<代码>:可能删除<代码> \n>代码>我应该注意排除<代码>状态< /代码>(最后行关键字)。。并且可能在窗格、窗口和状态之后添加\t
,以更好地确保它不会在不应该删除的时候删除\n
。得出以下结论:sed'n;/\n\(窗格\t\\窗口\t\\状态\t\)/!s/\n/;P;D'文件
,这似乎有效。我说的对吗?