您好,我有一个文件,其中包含多个标题,我需要将其转换为列值。该文件如下所示:
Day1
1,Smith,London
2,Bruce,Seattle
5,Will,Dallas
Day2
1,Mike,Frisco
4,James,LA
我希望文件最终看起来像这样:
Day1,1,Smith,London
Day1,2,Bruce,Seattle
Day1,5,Will,Dallas
Day2,1,Mike,Frisco
Day2,4,James,LA
该文件在名称之前没有连续数字,并且在" Day"之后它没有相同数量的记录。头。 有没有人对如何使用命令行完成此任务有任何想法?
答案 0 :(得分:6)
在awk中
awk -F, 'NF==1{a=$0;next}{print a","$0}' file
检查字段数是否为1,如果是,则设置变量并跳过下一个块。
对于没有1个字段的每一行,它会打印保存的变量和行
并在sed
sed -n '/,/!{h};/,/{x;G;s/\n/,/;p;s/,.*//;x}' file
为MrBones疯狂骑行打破了。
sed -n '
/,/!{h}; // If the line does not contain a comma overwrite buffer with line
/,/{ // If the line contains a comma, do everything inside the brackets
x; // Exchange the line for the held in buffer
G; // Append buffer to line
s/\n/,/; // Replace the newline with a comma
p; // Print the line
s/,.*//; // Remove everything after the first comma
x // exchange line for hold buffer to put title back in buffer for the next line.
}' file // The file you are using
本质上它保存了没有,
的行,即标题。然后,如果它不是标题,它将使用保存的标题切换当前行,并将现在切换的行追加到标题的末尾。因为它附加了换行符,然后下一个语句用逗号替换它。然后打印该行。 NExt恢复标题,删除它之后的所有内容并将其交换回缓冲区,为下一行做好准备。
答案 1 :(得分:3)
sed '/^Day/ {h;d;}
G;s/\(.*\)\n\(.*\)/\2,\1/
' YourFile
awk '{if ( $0 ~ /^Day/ ) Head = $0; else print Head "," $0}' YourFile
Day
作为段落分隔符,将内容用作标题,以便在以下行中使用答案 2 :(得分:2)
Perl解决方案:
#! /usr/bin/perl
use warnings;
use strict;
my $header;
while (<>) { # Read line by line.
if (/,/) { # If the line contains a comma,
print "$header,$_"; # prepend the header.
} else {
chomp; # Remove the newline.
$header = $_; # Remember the header.
}
}
答案 3 :(得分:1)
<强>的Perl 强>
$ perl -F, -wlane ' if(@F eq 1){$s=$F[0]; next}print "$s,$_"' file
Day1,1,Smith,London
Day1,2,Bruce,Seattle
Day1,5,Will,Dallas
Day2,1,Mike,Frisco
Day2,4,James,LA
答案 4 :(得分:1)
另一个sed版本
sed -n '/Day[0-9]\+/{h;b end};{G;s/\(.*\)\n\(.*\)/\2,\1/;p;:end}'
答案 5 :(得分:1)
这个Perl单行程序将按您的要求执行。它需要Perl v5.14或更高版本
perl -ne'tr/,// ? print $c,$_ : ($c = s/\s*\z/,/r)' myfile.txt
对于早期版本的perl,请使用
perl -ne'tr/,// ? print $c,$_ : ($c = $_) =~ s/\s*\z/,/' myfile.txt
<强>输出强>
Day1,1,Smith,London
Day1,2,Bruce,Seattle
Day1,5,Will,Dallas
Day2,1,Mike,Frisco
Day2,4,James,LA
答案 6 :(得分:0)
另一个perl示例 - 这次使用$/
来分隔每条记录。
use strict;
use warnings;
local $/ = "Day";
while (<>) {
next unless my ($num) = m/^(\d+)/;
for ( split /\n/ ) {
print "Day${num},$_\n" if m/,/;
}
}