使用awk或sed创建基于无关列的新行

时间:2016-01-15 00:36:21

标签: bash awk sed

我有一个看起来像这样的文件(列由标签分隔):

Owner    Phone    Car
Dan    111-111-1111    Avalon    Camry
Stacy    222-222-2222    Corolla    Yaris    Camry
Henry    333-333-3333    Prius

我希望所有额外的汽车都在自己的线以下(每个额外的车都复制了车主和手机信息)所以它看起来像这样:

Owner    Phone    Car
Dan    111-111-1111    Avalon
Dan    111-111-1111    Camry
Stacy    222-222-2222    Corolla        
Stacy    222-222-2222    Yaris
Stacy    222-222-2222    Camry
Henry    333-333-3333    Prius

我想知道是否有办法使用awk或sed(最好是一个班轮)实现这一点。

3 个答案:

答案 0 :(得分:8)

使用awk,您可以循环显示从3到结尾的字段,并将其与字段12一起打印:

awk '{for(i=3;i<=NF;i++){print $1,$2,$i}}' file

顺便说一句,如果你希望输出看起来很好地对齐,你可以输入column命令:

awk '{for(i=3;i<=NF;i++){print $1,$2,$i}}' file | column -t

答案 1 :(得分:1)

使用sed:使用换行符重复替换tabe并返回以获取分隔的单词,并在将模式空间打印到第一个嵌入换行符之前附加每个后续字段。

sed -n -e 's/\t/\n/g' -e 's/\n/\t/' -e 's/\n/\t/' -eP -e:l -e 's/\n/\t/' -eta -eb -e:a -e 's/\([^\t]*\t[^\t]*\)\t[^\t]*\(\t[^\t]*\)$/\1\2/' -etb -eb -e:b -eP -ebl < file

awk方式更容易:)

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed -r 's/\S+/\\S+/g;s/\s+/\\s+/g;s|^(.*)\\S\+|s/(\1)\\S+/\&\\n\\1/;\\//P;D|;q' file |
sed -rf - file

这将从文件的第一行(标题)构建一个sed脚本,然后针对该文件运行脚本,即如果标题包含三个字段,则构建以下脚本:

sed -r 's/^(\S+\s+\S+\s+)\S+/&\n\1/;//P;D' file

此脚本对前两个字段进行分组,并将它们(以换行符开头)附加到原始行。然后,如果模式匹配,则打印第一行然后删除并重复该过程,直到不再发生匹配为止。