【问题标题】:Merge two files using formula使用公式合并两个文件
【发布时间】:2021-03-10 02:19:01
【问题描述】:

我需要使用一些规则合并两个文件。第一个file1 有x 个用户,file2 有y 个用户;在文件 1 中,只有在 $4 时拥有 1 的用户可用。

它应该搜索文件的第 3 列,“IPxx”(IPxx 对每个用户都是唯一的,并且可以在 xx 中包含空格),并将其与文件 2 的第 5 列(没有 IP,xx 匹配xx)。如果找到匹配项,则使用此公式将两者合并(F1 是 File1;F2 是 File 2):

$2(F1):$1(F1):$2(F2):$1(F2) :$3(F1):yyyy/mm/dd(今天的日期)

我这样做是为了查找 File1 上的可用人员:

sed 's/\IP//' File1.txt | awk -F '(:)' '{if($4==1)print $2":"$1":"$3}'

并整理File2

awk -F '(:)' '{print $2":"$1":"$3}'

现在我如何比较它们两者并使用该公式将它们合并在一起?

例子:

文件1

123:bacon white:IPES:0
456:eggs grey:IPUS:1
789:ham yellow:IPUK:1

文件2

1:foo foo:ES:abc
2:bar bar:US:def
3:tmp tmp:ES:ghi
4:baz baz:UK:jkl
5:qux qux:US:mno
6:spam spam:UK:pqr
7:xyz xyz:UK:stu

输出文件

eggs grey:456:bar bar:2:IPUS:2021/03/10
eggs grey:456:qux qux:5:IPUS:2021/03/10
ham yellow:789:baz baz:4:IPUK:2021/03/10
ham yellow:789:spam spam:6:IPUK:2021/03/10
ham yellow:789:xyz xyz:7:IPUK:2021/03/10

【问题讨论】:

  • 既然 file1 第 1 行有ES,而 file2 第 1 行和第 3 行有ES,为什么不显示bacon white:123:foo foo:1:IPES:2021/03/10EStmp tmp 也一样?
  • 因为 123:bacon white:IPES:0 以 0 结尾,所以只有以 1 结尾的才可用

标签: linux bash sorting awk sed


【解决方案1】:
$ awk -v date="$(date +"%Y/%m/%d")" '
            BEGIN   {FS=OFS=":"} 
            NR==FNR {f3=$3; sub(/^IP/,"",f3); a[f3]=$0; next} 
            $3 in a {split(a[$3],p); 
                     print p[2],p[1],$2,$1,p[3],date}' file1 file2

bacon white:123:foo foo:1:IPES:2021/03/09
eggs grey:456:bar bar:2:IPUS:2021/03/09
bacon white:123:tmp tmp:3:IPES:2021/03/09
ham yellow:789:baz baz:4:IPUK:2021/03/09
eggs grey:456:qux qux:5:IPUS:2021/03/09
ham yellow:789:spam spam:6:IPUK:2021/03/09
ham yellow:789:xyz xyz:7:IPUK:2021/03/09

ES 也匹配,不确定它们不在您的预期输出中。

在扫描第一个文件 (NR==FNR) 时,通过从第三列剥离前缀来构造键,并将带有该键的整个记录​​保存在映射中(为了不首先修改分配给临时变量的第三个字段)。

对于第二个文件,检查第三个字段是否在地图中,如果是,则拆分之前保存的记录并提取字段并按顺序打印。

将所需格式的日期作为变量传递给脚本并打印出来。

如果要根据第4个字段值排除记录,请在映射阶段添加过滤器

NR==FNR {if($4) {f3=$3 ... }}

【讨论】:

  • 至少根据我的阅读,这是他正在寻找的,尽管我仍然对他为什么显示他所做的输出感到困惑??
  • 因为 123:bacon white:IPES:0 以 0 结尾,所以只有以 1 结尾的才可用。但我只是删除了匹配模式的每一行。谢谢你
  • @TsYn 请查看更新的解释和过滤不需要的记录。
【解决方案2】:

使用 GNU 命令行实用程序 joingrepsedsortdate 的解决方案:

today=$(date +%Y/%m/%d)
join -t: -j3 -o1.2,1.1,2.2,2.1,1.3 \
  <(grep ':1$' file1 | sort -t: -k3,3) \
  <(sed -E 's/([^:]*)(:[^:]*)$/IP\1\2/' file2 | sort -t: -k3,3) |
sed "s%\$%:${today}%" |
sort -t: -n -k2,2

输出:

eggs grey:456:bar bar:2:IPUS:2021/03/10
eggs grey:456:qux qux:5:IPUS:2021/03/10
ham yellow:789:baz baz:4:IPUK:2021/03/10
ham yellow:789:spam spam:6:IPUK:2021/03/10
ham yellow:789:xyz xyz:7:IPUK:2021/03/10

【讨论】:

    【解决方案3】:

    这可能对你有用(GNU sed 和排序):

    sed -nE '1{x;s/^/cat file1/e;x};G
             s#^([^:]*):([^:]*):(..):(...)(\n[^\n]*)*\n([^:]*):([^:]*):(IP\3):1.*#\7:\6:\2:\1:\8:'"$(date +%Y/%m/%d)"'#p' file2 |
    sort -k2,2n
    

    将 file1 复制到保留空间中。

    将文件 1 附加到文件 2 的每一行,并从复合行中按所需顺序提取详细信息。

    按数字字段 2 对输出进行排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      • 2020-03-22
      • 2019-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多