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

Bash 使用awk或sed基于无关列创建新行,bash,awk,sed,Bash,Awk,Sed,我有一个类似这样的文件(列由选项卡分隔): 我希望所有额外的车辆都位于原始车辆的下方(每增加一辆车,都会复制车主和电话信息),因此看起来如下所示: 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

我有一个类似这样的文件(列由选项卡分隔):

我希望所有额外的车辆都位于原始车辆的下方(每增加一辆车,都会复制车主和电话信息),因此看起来如下所示:

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(最好是一个单行程序)来实现这一点。

使用
awk
您可以在
3
到结尾的字段之间循环,并将其与字段
1
2
一起打印:

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

使用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
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-e-eP-ebl
awk方法更简单:)

这可能适合您(GNU-sed):

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

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

该脚本将前两个字段分组,并将它们(以换行符开头)追加到原始行。然后,如果图案匹配,则打印第一行,然后删除,并重复该过程,直到不再匹配。

Rick,所有字段和所有车辆是否由制表符分隔?是的,因为制表符属于awk的默认字段分隔符集。
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
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 -r 's/^(\S+\s+\S+\s+)\S+/&\n\1/;//P;D' file