Bash 将与图案匹配的线移动到上一行
我有一个有结构的文件Bash 将与图案匹配的线移动到上一行,bash,sed,awk,vim,Bash,Sed,Awk,Vim,我有一个有结构的文件 12312 desc: bleh... 9938 desc: blah... desc: bloh... desc: blih... desc: bluh... 9912 desc: blah... 我想将匹配模式“desc:”的行移到前一行,或者删除每个模式“desc:”前面的行中的“\n” 期望输出: 12312 desc: bleh... 9938 desc: blah... desc: bloh... desc: blih... desc: bluh... 99
12312
desc: bleh...
9938
desc: blah...
desc: bloh...
desc: blih...
desc: bluh...
9912
desc: blah...
我想将匹配模式“desc:”的行移到前一行,或者删除每个模式“desc:”前面的行中的“\n” 期望输出:
12312 desc: bleh...
9938 desc: blah... desc: bloh... desc: blih... desc: bluh...
9912 desc: blah...
我试过了
awk '!/desc:/{
printf "%s ",$0
getline
printf "%s \n",$0
}
/desc/{print}' file
没有结果
实际上,所有数据都是awk-F\“{print$4”\t“$6}”的输出。
也许我可以先做点什么?用
awk
单程:
$ awk '!/^desc:/&&NR>1{print OFS}{printf "%s ",$0}END{print OFS}' file
12312 desc: bleh...
9938 desc: blah... desc: bloh... desc: blih... desc: bluh...
9912 desc: blah...
说明:
!/^desc:///code>匹配不以
开头的行,不包括文件desc:
中的第一行NR>1
在匹配行之前打印一个输出字段分隔符。在{print of s}
中,OFS的默认值为awk
\n
打印每一行,不带尾随换行符{printf“%s”,$0}
读取文件后添加一个尾随换行符END{print of s}
perl -pe 's/\n/ /; ! /^desc:/ and print "\n" unless 1 == $.' FILE
sed
oneliner
sed ':a $!N;s/\ndesc/ desc/;ta P;D'
将输出
12312 desc: bleh...
9938 desc: blah... desc: bloh... desc: blih... desc: bluh...
9912 desc: blah...
使用
script.vim的内容
:
set backup
g/\v^desc/ normal kJ
saveas! output.txt
q!
像这样运行:
vim -u NONE -N -S script.vim infile
它将创建一个包含以下内容的output.txt
文件:
12312 desc: bleh...
9938 desc: blah... desc: bloh... desc: blih... desc: bluh...
9912 desc: blah...
使用“新”GNU选项-z
,您可以使用
| sed -z 's/\ndesc:/ desc:/g'
无法获取它:
desc:blah…
不匹配9912
,但它会移动到它。您能澄清您的问题吗?我想将与模式“desc:”匹配的行移动到上一行,或删除每个模式“desc:”之前的行中的“\n”:“。使用getline通常是错误的方法,在这种情况下确实如此。在阅读并完全理解所有注意事项之前,不要考虑使用getline。你不能解释一下吗。我不相信同样的结果。实际上,所有数据都是awk-F\“{print$4”\t“$6}”
@IgorVoltaic的输出。我已经添加了一个解释。数据来自何处并不重要,只要它是问题中描述的格式就行。说你没有得到相同的结果没有帮助。结束{print of s}
将在每行末尾添加一个空格,使用end{print”“}
仅打印一个换行符。您还可以使用printf“%s”,而不是printf“%s”,在每行末尾添加第二个空格“,$0
但您需要重新考虑脚本逻辑来解决这个问题。@Jaypal-这是处理连接行的常见awk方法。您可能需要在每行之前打印一个ORS(如果它是输入中的第一行,则不打印任何内容)或OFS,这取决于它是块中的第一行还是后续行,因此您只需使用三元表达式来捕获区分块中第一行和后续行的条件。True,只是在printf
内部使用三元运算符
非常好。如果1==$,使用print“\n”不是更直观吗/^描述:/
?我想是/^desc:/并打印“\n”,除非1==$。
表示如果找不到desc,则打印换行,除非行上只有一个字段
。这是一个相当令人讨厌的陈述,因为它至少包含了一些负面因素。难道没有更清晰的方式来写吗?我看到建议打印“\n”,除非1==$。||/^desc://
在注释中,但是如果($.>1 | |//^desc:/)在perl中打印“\n”,您就不能写一些清晰而简单的东西吗?我甚至不知道这是否正确解释了最初的perl意图。好吧,这说明了我是如何做到这一点的:我从和
开始,注意到开头的空行,所以添加了,除非。
| sed -z 's/\ndesc:/ desc:/g'