awk:在生成数据时保留行顺序并删除重复的字符串(镜像)

awk: preserve row order and remove duplicate strings (mirrors) when generating data

我有两个文本文件

g1.txt

 alfa beta;www.google.com
 Light Dweller - CR, Technical Metal;http://alfa.org;http://beta.org;http://gamma.org;

g2.txt

Jack to ride.zip;http://alfa.org;
JKr.rui.rar;http://gamma.org;
Nofj ogk.png;http://gamma.org;

我将此命令用于 运行 我的 awk 脚本

awk -f ./join2.sh g1.txt g2.txt > "g3.txt"

我得到了这个输出

Light Dweller - CR, Technical Metal;http://alfa.org;http://beta.org;http://gamma.org;;Jack to ride.zip;http://alfa.org;JKr.rui.rar;http://gamma.org;Nofj ogk.png;http://gamma.org;
alfa beta;www.google.com;

有什么问题?

1.行顺序不守恒,例如在输出文件g3.txt中,行alfa beta;www.google.com;在行Light...之后。什么时候应该是第一个,正如您在 g1.txt
中看到的那样 2. 我在Light..行有很多镜像字符串,你可以在g3.txt

中看到
http://alfa.org
http://gamma.org
http://gamma.org

在同一行重复。

我想要什么样的行输出? 像这样:

alfa beta;www.google.com
Light Dweller - CR, Technical Metal;http://alfa.org;http://beta.org;http://gamma.org;Jack to ride.zip;JKr.rui.rar;Nofj ogk.png;

首先: 我尝试实现一个函数来检查一行中是否有普通字符串,例如你在我的行输出中看到 Light Dweller - CR, Technical Metal... 有该行内的字符串相同吗?例如 http://alfa.orghttp://gamma.org ?好吧,我不要这个。 我想要每个字符串,用分隔符括起来;仅出现一次,并且每行仅出现一次。
此规则应仅适用于输出文件,g3.txt

其次: 我希望 g1.txt 中的原始行顺序必须保留在 g3.txt 输出文件中。例如,在 g1.txt 我有

alfa beta ... 
Light Dweller ... 

但是我的脚本 returns 对我来说是不同的顺序

Light Dweller ...
alfa beta ... 

我想防止行重新排序

我的join2.sh脚本是这样的

#! /usr/bin/awk  -f

BEGIN {
  OFS=FS=";"
  C=0;
}
{
  if (ARGIND == 1) {
     X = $NF
     T0[$NF] = C++
     $NF = ""
     if (T1[X]) {
        T1[X] = T1[X] [=18=]
     } else {
        T1[X] = [=18=]
     }
  } else {
     X = $NF
     T0[$NF] = C++
     $NF = ""
     if (T2[X]) {
        T2[X] = T2[X] [=18=]
     } else {
        T2[X] = [=18=]
     }
  }
}

END {
  for (X in T0) {
    # concatenate T1[X] and X, since T1[X] ends with ";"
    print T1[X]  X, T2[X]
  }
}

解决方案:

您应该首先像这样处理 g2.txt

cat join2.awk

BEGIN {
  OFS=FS=";"
}
ARGIND == 1 {
   map[] = ( in map ? map[] OFS : "") 
   next
}
{
   r = [=10=];
   for (i=1; i<=NF; ++i)
      if ($i in map)
         r = r OFS map[$i]
   [=10=] = r
}
1

然后将其用作:

awk -f join2.awk g2.txt g1.txt
alfa beta;www.google.com
Light Dweller - CR, Technical Metal;http://alfa.org;http://beta.org;http://gamma.org;;Jack to ride.zip;JKr.rui.rar;Nofj ogk.png