将两行合并为一个特定模式的文件中的一行

时间:2014-04-09 11:22:14

标签: shell sed awk

我是shell脚本的新手。我有这样的输入

abc
 xyz
cdf
kjd
mno
abc
 xyzjhd
lkds
kmdew
abc
  yzxnh

我需要输出格式

abcxyz
cdf
kjd
mno
abcxyzjhd
lkds
kmdew
abcyzxnh

8 个答案:

答案 0 :(得分:2)

sed是在单行上进行简单替换的优秀工具*,对于所有其他文本操作,标准UNIX工具是awk。这个问题涉及多行(特别是连接2行)的事情,因此sed不应该考虑解决方案,因此你需要一个awk解决方案。

这使用GNU awk将文件中的所有行读取为单个字符串,然后删除所有出现的换行符,后跟该字符串中的空白字符:

$ awk -v RS='^$' -v ORS= '{gsub(/\n[[:blank:]]+/,"")}1' file
abcxyz
cdf
kjd
mno
abcxyzjhd
lkds
kmdew
abcyzxnh

请注意,上面使用不包含换行符的[:blank:]字符类,所以它将执行的操作是将一行以空白字符开头到前一行。

* sed具有跨多行处理的语言结构,但这些结构在1970年代中期发明awk时已经过时了。唯一仍然适合使用的sed语言结构是s,g和p(带-n)。如果您需要sed中的任何其他内容,那么您使用的是错误的工具。

答案 1 :(得分:1)

GAWK:

kent$  awk -v RS="" '{gsub(/\n\s+/,"")}7' file   
abcxyz
cdf
kjd
mno
abcxyzjhd
lkds
kmdew
abcyzxnh

答案 2 :(得分:1)

您可以尝试此sed

sed 'N;/\n .*/{s/\n//; s/ \+//;};P;D' yourfile

sed 'N;/\n .*/{s/\n \+//;};P;D' yourfile

如果想要就地编辑,

sed -i.bak 'N;/\n .*/{s/\n \+//;};P;D' yourfile

答案 3 :(得分:1)

另一个awk

awk 'NR>1{ORS=sub(/^[[:blank:]]+/,x)?x:RS; print p} {p=$0} END{ORS=RS; print p}' file

答案 4 :(得分:1)

这可能适合你(GNU sed):

sed '$!N;s/\n  *//;P;D' file

如果行的开头有空格,请阅读下一行并删除上一行换行符和以下任何空格。

如果可能有多条这样的行,那么:

sed ':a;$!N;s/\n  *//;ta;P;D' file

答案 5 :(得分:0)

这个awk成功了:

$ awk '/^ / {gsub(/^[ ]*/, ""); print a$0; a=""; next} {if (a) print a; a=$0}' file
abcxyz
cdf
kjd
mno
abcxyzjhd
lkds
kmdew
abcyzxnh

解释

  • /^ / {}在以空格开头的行上,执行{}
  • {gsub(/^[ ]*/, ""); print a$0; a=""; next}删除所有前导空格并将前一行与当前行一起打印。然后跳到下一行。
  • {if (a) print a; a=$0}否则,如果设置了a,则打印上一行。另外,将当前的一个存储在a变量中。

答案 6 :(得分:0)

sed -n '1h;1!H;${x;s/\n //g;p}' YourFile
与@sat相同的想法,但整个文件在内存中,并使用g

更改一次

答案 7 :(得分:0)

perl -0777 -pe 's/\n\s+//g' file

或者要加入的行始终以abc开头:

perl -0777 -pe 's/(abc)\s*\n\s+/$1/g' file