问题
我有一个文本文件,其格式如下:第一行为 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
如何把两行合并成一行?
回答
使用 awk 命令
awk 'NR%2{printf "%s, ",$0;next;}1' yourFile
是一个使用awk
工具对名为yourFile
的文件进行操作的命令。下面对该命令进行详细解释:
-
awk
:这是一个强大的文本处理工具,它逐行读取输入文件(此处为yourFile
),根据提供的模式和动作对每一行进行处理。 -
'{...}'
:这是awk
命令中的脚本块,其中包含了一系列针对每一行的模式(条件)和动作(命令)。在这行命令中,脚本块内有两个部分,由;
分隔。 -
NR%2
:这里的NR
是awk
内置变量,表示当前处理的行号(Number of Record)。NR%2
计算NR
除以2的余数。如果余数为非零(即奇数行),表达式求值为真(True)。 -
printf "%s, ", $0;
:如果NR%2
为真(即当前行是奇数行),执行以下动作:printf
函数用于格式化输出字符串。%s
是格式占位符,表示要打印的字符串;$0
代表当前行的完整文本内容。,
是紧跟在%s
后面的字符串,表示在输出的行内容之后添加逗号和空格作为分隔符。- 整个
printf
语句的作用是打印当前行的内容($0
),并在其后附加一个逗号和空格。
-
next
:紧跟在printf
之后的next
关键字指示awk
跳过后续的所有动作,直接开始处理下一行。这意味着在奇数行上执行完printf
后,不会继续执行后面的1
(默认动作),而是直接转到下一行。 -
1
:在awk
中,任何非零数值(如1
)都表示真(True),可以视为一个简化的模式,表示“对于所有行”。当没有指定具体的模式时,这个1
就相当于一个默认的动作,即打印当前行($0
)。这里由于前面有next
,所以只有偶数行才会执行到这个1
,直接打印该行内容。
综上所述,此awk
命令的作用是:
- 对于
yourFile
中的奇数行(NR%2
为真),将其内容输出并追加一个逗号和空格; - 跳过执行后续的默认打印动作(
next
); - 对于偶数行,由于没有执行
printf
,awk
会执行默认的动作,即print $0
,输出当前行的内容(包括换行符)。 - 这个过程会一直重复,直到文件的最后一行。
最终效果是将 yourFile
中的每相邻两行合并为一行,中间以逗号和空格分隔。例如,如果原始文件 yourFile
内容如下:
Line1
Line2
Line3
Line4
经过上述命令处理后,输出将是:
Line1, Line2
Line3, Line4
使用 sed 命令
sed 'N;s/\n/, /' yourFile
是对名为 yourFile
的文件使用 sed
工具进行操作的命令。下面对命令进行详细解释:
-
sed
:这是一种流编辑器,用于对文本进行逐行或模式匹配下的编辑操作。它读取输入(此处为yourFile
文件),根据提供的命令对每一行或选定的行进行修改,并将结果输出。 -
'N;s/\n/, /'
:这是传递给sed
的命令序列,包含两个部分,由分号 (;
) 分隔。a.
N
:N
是sed
的命令之一,它的作用是读取下一行(Next line),并将当前行与下一行合并为一个临时缓冲区,用换行符 (\n
) 分隔。这意味着在执行N
命令后,sed
的工作空间中将同时包含当前行(即原始的“当前行”)和下一行的内容。
b.
s/\n/, /
:s
是sed
中的替换(Substitute)命令,用于查找并替换文本中的模式。\n
表示换行符。在这里,它代表了由N
命令引入的临时缓冲区中当前行与下一行之间的分隔符。/, /
指定了要替换\n
的内容,即逗号后跟一个空格(,
)。这表示将两行之间的换行符替换为逗号和空格连接的字符串。
综上所述,此 sed
命令的作用是:
- 对于
yourFile
中的每一行,首先使用N
命令将其与下一行合并为一个临时缓冲区,两者之间以换行符分隔; - 然后应用
s/\n/, /
命令,将临时缓冲区中的换行符替换为逗号和空格连接的字符串,从而实现将相邻两行连接成一行,并以逗号加空格作为分隔的效果; - 连接后的行作为新的输出行,被
sed
打印出来。
参考:
- stackoverflow question 9605232
- man awk
- man sed
相关阅读: