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将退出。

另一答案

下面你会找到两个基于awksed的解决方案。这两种解决方案都是通用的,这意味着我们不知道在使用正则表达式/..:..:../识别的两个时间字符串之间放置了多少记录/行:

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的情况下被调用,因此默认情况下会在退出时打印剩余的模式缓冲区。

另一答案

还有两个解决方案结合echocatsed

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 - 将带有模式的行转换为列的主要内容,如果未能解决你的问题,请参考以下文章

将具有动态日期的行转换为列

如何将具有重复值的行转换为列?

根据公共列值将定义的行数转换为列

将 Pandas DataFrame 的行转换为列标题,

如何在sql中将行转换为列

不能从子查询将行转换为列