我有一个如下格式的文本文件。第一行是“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

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


当前回答

最简单的方法是:

删除偶数行,并将其写入某个临时文件1。 删除奇数行,并将其写入某个临时文件2。 使用粘贴命令和-d(表示删除空格)将两个文件合并为一个文件

Sed '0~2d'文件> 1 && & Sed '1~2d'文件> 2 && &粘贴-d " " 1 2

其他回答

这是我在bash中的解决方案:

while read line1; do read line2; echo "$line1, $line2"; done < data.txt

与glenn jackman使用粘贴的回答略有不同:如果-d分隔符选项的值包含多个字符,则逐个粘贴这些字符,并结合-s选项在处理相同输入文件时继续这样做。

这意味着我们可以使用任何我们想要的分隔符加上转义序列\n来一次合并两行。

使用逗号:

$ paste -s -d ',\n' infile
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

还有美元符号:

$ paste -s -d '$\n' infile
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

它不能做的是使用由多个字符组成的分隔符。

作为奖励,如果粘贴是POSIX兼容的,这将不会修改文件中最后一行的换行符,因此对于具有奇数行数的输入文件,如

KEY 4048:1736 string
3
KEY 0:1772 string

粘贴不会在最后一行添加分隔字符:

$ paste -s -d ',\n' infile
KEY 4048:1736 string,3
KEY 0:1772 string

更通用的解决方案(允许连接多个后续行)是shell脚本。这在每一个之间增加了一条线,因为我需要可见性,但这很容易补救。在这个例子中,“key”行以:结尾,而其他行没有。

#!/bin/bash
#
# join "The rest of the story" when the first line of each   story
# matches $PATTERN
# Nice for looking for specific changes in bart output
#

PATTERN='*:';
LINEOUT=""
while read line; do
    case $line in
        $PATTERN)
                echo ""
                echo $LINEOUT
                LINEOUT="$line"
                        ;;
        "")
                LINEOUT=""
                echo ""
                ;;

        *)      LINEOUT="$LINEOUT $line"
                ;;
    esac        
done

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

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

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

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。