我有一个如下格式的文本文件。第一行是“KEY”,第二行是“VALUE”。

KEY 4048:1736 string
3
KEY 0:1772 string
1
KEY 4192:1349 string
1
KEY 7329:2407 string
2
KEY 0:1774 string
1

我需要这个值和键在同一行。所以输出应该是这样的…

KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1

如果我可以使用一些分隔符,如$或:

KEY 4048:1736 string , 3

我如何将两条线合并成一条?


当前回答

perl -0pE 's{^KEY.*?\K\s+(\d+)$}{ $1}msg;' data.txt > data_merged-lines.txt

-0读取整个文件,而不是逐行读取; pE用循环包装代码并打印输出,详见http://perldoc.perl.org/perlrun.html; ^KEY匹配行首的“KEY”,后面是序列前任何(.*?)的非贪婪匹配

一个或多个空格\s+,包括换行符; 一个或多个数字(\d+),我们捕获并重新插入为$1;

后跟$的末尾。

\K方便地从替换中排除左边的所有内容,因此{$1}只替换1-2个序列,参见http://perldoc.perl.org/perlre.html。

其他回答

你可以像这样使用awk来合并2对行:

awk '{ if (NR%2 != 0) line=$0; else {printf("%s %s\n", line, $0); line="";} } \
     END {if (length(line)) print line;}' flle

如果Perl是一个选项,您可以尝试:

perl -0pe 's/(.*)\n(.*)\n/$1 $2\n/g' file.txt

您也可以使用以下vi命令:

:%g/.*/j
perl -0pE 's{^KEY.*?\K\s+(\d+)$}{ $1}msg;' data.txt > data_merged-lines.txt

-0读取整个文件,而不是逐行读取; pE用循环包装代码并打印输出,详见http://perldoc.perl.org/perlrun.html; ^KEY匹配行首的“KEY”,后面是序列前任何(.*?)的非贪婪匹配

一个或多个空格\s+,包括换行符; 一个或多个数字(\d+),我们捕获并重新插入为$1;

后跟$的末尾。

\K方便地从替换中排除左边的所有内容,因此{$1}只替换1-2个序列,参见http://perldoc.perl.org/perlre.html。

"ex"是一个可脚本化的行编辑器,与sed、awk、grep等属于同一家族。我觉得这可能就是你要找的东西。许多现代vi克隆/后继者也有一个vi模式。

 ex -c "%g/KEY/j" -c "wq" data.txt

这就是说,对于每一行,如果它匹配"KEY"执行下一行的j。该命令完成后(针对所有行),发出一个w rite和q uit。