bash/awk/sed/。。连接共享条目的行,反之亦然

bash/awk/sed/。。连接共享条目的行,反之亦然,bash,awk,concatenation,Bash,Awk,Concatenation,我想知道如何将一个文件的行与多个列和行连接起来,对于共享第1列中相同条目的行,>100mb的文件。以及如何取消以这种方式连接的文件的连接 例如: 从file.txt: a 3494 3929 asd 12 fdfdf b 2323 2390 kjk 32 kjkjk b 1323 2390 kjk 32 kjkjk c 2399 9009 dfd 90 sasd c 9090 1212 jkk 01 kjkk c 0900 2311 gfg 09 dkjs d 0909 2322 kjk 98

我想知道如何将一个文件的行与多个列和行连接起来,对于共享第1列中相同条目的行,>100mb的文件。以及如何取消以这种方式连接的文件的连接

例如:

从file.txt:

a 3494 3929 asd 12 fdfdf
b 2323 2390 kjk 32 kjkjk
b 1323 2390 kjk 32 kjkjk
c 2399 9009 dfd 90 sasd
c 9090 1212 jkk 01 kjkk
c 0900 2311 gfg 09 dkjs
d 0909 2322 kjk 98 dskk
d 0909 0903 kjk 98 dskk
d 0909 2422 fdd 98 cvcv
到,concatenatedfile.txt

a 3494 3929 asd 12 fdfdf
b 2323 2390 kjk 32 kjkjk b 1323 2390 kjk 32 kjkjk
c 2399 9009 dfd 90 sasd c 9090 1212 jkk 01 kjkk c 0900 2311 gfg 09 dkjs
d 0909 2322 kjk 98 dskk d 0909 0903 kjk 98 dskk d 0909 2422 fdd 98 cvcv

另一种方法是:从concatenatedfile.txt->file.txt尝试这样做需要大于100MO的RAM:

awk '
    {for (i=2; i<=NF; i++) arr[$1]=arr[$1]" "$i}
    END{for (a in arr) print a, arr[a]}
' file.txt

不带数组的备选方案如果字段1按连续顺序排列,请尝试:

awk 'END{print RS} p!=$1{if(p)print RS; p=$1}1' ORS= file
相反,请尝试以下操作:

awk '{for(i=2; i<=NF; i+=1) if( $i==$1 ) $i=RS $i}1' file

但如果其他字段中的一个字段的值与重建记录的第一个字段的值相同,则该操作将失败,在这种情况下,您需要进行额外检查。

在awk中,取消链接相当简单:


如果您愿意,您可以省略垃圾处理—默默地忽略不匹配的数据。

具有相同列1的行是否总是彼此相邻(如您的示例所示),或者它们是否会被洗牌?在我的文件中,它们彼此相邻,但我想对它们进行排序很容易?
awk '{for(i=2; i<=NF; i+=1) if( $i==$1 ) $i=RS $i}1' file
awk 'NF % 6 != 0 { print "Garbage: ", $0 }
     NF % 6 == 0 { for (i = 1; i < NF; i += 6)
                   {
                       pad = ""
                       for (j = i; j < i+6; j++)
                       {
                           printf "%s%s", pad, $j
                           pad = " "
                       }
                       print ""
                   }
                 }'
awk 'NF % 6 != 0 { printf "\nGarbage: %s\n", $0 }
     NF % 6 == 0 { if ($1 != old && NR > 1) print ""
                   if ($1 != old) printf "%s", $0
                   else           printf " %s", $0
                   old = $1
                 }
     END         { print "" }'