如何在bash中将列转换为行

时间:2017-06-03 07:05:43

标签: bash awk sed

我正在尝试重新安排我的文本文件:

Record    :   Field1
              Field2
              Field3
Record    :   Field1 
Record    :   Field1
Record    :   Field1
              Field2
              Field3 
              Field4 
              Field5 

如何使用awk或sed重新排列它以使我的输出看起来像这样?

Field1, Field2, Field3
Field1
Field1
Field1, Field2, Field3, Field4, Field5

6 个答案:

答案 0 :(得分:2)

$ awk -v OFS=', ' '{printf "%s%s", (/^Record/?ors:OFS), $NF; ors=ORS} END{print ""}' file
Field1, Field2, Field3
Field1
Field1
Field1, Field2, Field3, Field4, Field5

答案 1 :(得分:0)

awk 解决方案:

awk 'NF==3{ if(s){ printf("%s\n",s) } s=$3; next }{ s=s", "$1 }END{ if(s) print s }' file

输出:

Field1, Field2, Field3
Field1
Field1
Field1, Field2, Field3, Field4, Field5
  • NF==3 - 遇到3个字段的行(将空格视为字段分隔符)

  • if(s){ printf("%s\n",s) - 将以前处理过的/ 转置列打印为单个字符串

  • s=$3; - 将第3个字段作为" 开始转置阶段"

  • s=s","$1 - 累积从属列值

答案 2 :(得分:0)

为了sed的乐趣:

sed -En "/^Record/!{s/^\s*/, /;H};/^Record\s*:\s*/{s///;x;s/\n//g;p};${s///;x;s/\n//g;p};" file
  • 如果输入不是记录的开始/^Record/!
    • 用逗号{s/^\s*/, /;
    • 替换前导空格
    • 并添加到历史记录H};
  • 如果输入是记录的开头/^Record\s*:\s*/
    • 修剪标题{s///;
    • 交换历史x;
    • 打印单行历史;s/\n//g;p};
  • 与上一个输入行${s///;x;s/\n//g;p};
  • 相同

答案 3 :(得分:0)

特别处理第一张唱片,直接打印3美元。

对于以下记录,请添加' \ n'在打印$ 3之前,或者打印$ 1否则。

请参考以下简单的解决方案。

awk 'NR==1{printf "%s",$3;next}
   {if($1=="Record"){printf"\n%s",$3} else {printf ",%s",$1}}
   END{printf "\n"}
'

输出:

Field1,Field2,Field3
Field1
Field1
Field1,Field2,Field3,Field4,Field5

答案 4 :(得分:0)

使用简单的printf条件再试一次awk。

awk '{printf("%s%s",/^Record/?$3:$1,/^Record/&&NR>1?RS:FS)} END{print ""}'  Input_file

使用2%s的简单printf打印2个字符串。因此,第一个字符串将根据条件打印/ ^记录/如果一行从它开始然后打印第三个字段,否则打印第一个字段。与第二个字符串类似,条件是如果一行以/ ^ record /并且行不是第一行,则打印RS(记录分隔符,其默认值为新行)否则打印FS(默认值为空格的字段分隔符)。

答案 5 :(得分:0)

这可能适合你(GNU sed):

sed '/^Record.*:\s*/{s///;:a;N;s/\s*\n\s\+/, /;ta;P;D}' file

专注于以Record开头,后跟多个字符的行,然后是:,最后是一些空格。使用匹配删除此行的前面。附加下一行(如果有的话)并替换任何带有,和空格的空格的换行符。必要时重复,然后打印该行并重复。