linux - 将带有模式的行转换为列
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux - 将带有模式的行转换为列相关的知识,希望对你有一定的参考价值。
大家。
这种具有特定模式的转置事物从行到列一直困扰着我。
我想把下面的行改成列,比如
从
20:20:10
abc_flow.out
sss_flow.out
20:20:11
bcd_flow.out
qcd_flow.out
至
20:20:10 abc_flow.out sss_flow.out
20:20:11 bcd_flow.out qcd_flow.out
谢谢!
当且仅当您的Input_file与所示示例相同(相同)时,才使用简单的xargs
。
xargs -n3 < Input_file
来自man xargs
:
-n max-args每个命令行最多使用max-args参数。如果超出大小(参见-s选项),将使用少于max-args的参数,除非给出-x选项,在这种情况下xargs将退出。
下面你会找到两个基于awk
和sed
的解决方案。这两种解决方案都是通用的,这意味着我们不知道在使用正则表达式/..:..:../
识别的两个时间字符串之间放置了多少记录/行:
awk
:
awk 'BEGIN{ORS=OFS}/..:..:../&&(NR!=1){printf "
"}1;END{printf "
"}' <file>
这里我们将输出记录分隔符(ORS
)设置为等于输出字段分隔符(OFS
)。这意味着默认情况下,一切都将以一行结束。但是,每次我们找到表示时间字符串的记录时,我们都会打印换行符。
它基本上检查行是否是时间,如果是,则打印换行符。对于其余部分,它将所有记录打印在一行中(ORS=OFS
::输出记录分隔符是输出字段分隔符)。
备注:END{printf "
"}
只打印最终的换行符并不是必需的。这取决于您的要求。
sed
:
sed ':a;N;/..:..:..$/{P;D};s/
/ /;ba' <file>
理解这只是纯粹的sed
wtf。理解这一点的方法最好一步一步完成:
:a
创建了一个标签a
N
将新行附加到模式缓冲区/..:..:..$/{P;D}
如果模式缓冲区以时间字符串结尾,则将模式缓冲区打印到第一个换行符(P
),然后删除相同的部分(D
)。s/ / /
用空格替换模式缓冲区中的换行符。ba
转到标签a
由于sed
在没有-n
的情况下被调用,因此默认情况下会在退出时打印剩余的模式缓冲区。
还有两个解决方案结合echo
,cat
和sed
:
echo $(cat file.txt) | sed 's/ ([0-9])/
1/g'
或者使用paste
命令:
paste -d " " - - - < file.txt
默认情况下,paste命令用tab,Tab替换换行符
。但是,在这种情况下,我们想用空格替换
,所以我们需要-d " "
。要限制每次我们需要短划线占位符-
时粘贴的行数。在这种情况下,由于输入数据的结构,我们需要三个破折号。
另一个awk
$ awk '/[0-9:]/{if(line) print line; line=$0; next}
{line=line OFS $0}
END {if(line) print line}' file
20:20:10 abc_flow.out sss_flow.out
20:20:11 bcd_flow.out qcd_flow.out
如有必要,您可以优化正则表达式匹配。
您可以使用以下sed
命令:
$ (tr '
' ' ' < file; echo '' ) | sed 's/ ([0-9]{1,2}:[0-9]{1,2}:)/
1/g'
测试:
$ cat file
20:20:10
abc_flow.out
sss_flow.out
20:20:11
bcd_flow.out
qcd_flow.out
$ (tr '
' ' ' < file; echo '' ) | sed 's/ ([0-9]{1,2}:[0-9]{1,2}:)/
1/g'
20:20:10 abc_flow.out sss_flow.out
20:20:11 bcd_flow.out qcd_flow.out
说明:
tr
命令会将所有EOL
转换为spaces
,然后sed
命令将替换空格,然后用
替换时间戳,然后反向引用时间戳,以便分隔不同行上的记录。
rs
命令用于重塑这样的数组。我们可以要求它将换行视为分隔符(-e
),并重新整形为三列(0 3
)中每一行的未知行数:
$ rs -e 0 3 <<END
20:20:10
abc_flow.out
sss_flow.out
20:20:11
bcd_flow.out
qcd_flow.out
END
20:20:10 abc_flow.out sss_flow.out
20:20:11 bcd_flow.out qcd_flow.out
我们可以添加-C' '
和-z
以获得更紧凑的输出:
20:20:10 abc_flow.out sss_flow.out
20:20:11 bcd_flow.out qcd_flow.out
以上是关于linux - 将带有模式的行转换为列的主要内容,如果未能解决你的问题,请参考以下文章