在 Unix 上根据列值以特定排序顺序将行从 File1、File2 追加到 File3

在 Unix 上根据列值以特定排序顺序将行从 File1、File2 追加到 File3

我已经在网上搜索了一个星期,但似乎找不到任何适合我的场景的解决方案。我有两个文件。

File1 包含许多列,但最后一列是参考号。并将用作驱动文件。

文件1的内容:

file1abc|file1abc|file1123|9999999    
file1def|file1def|file1456|8888888

File2 也包含许多列,但参考号重复,并且有一个必需的排序字段

文件2内容

file2xyz|file2xyz|file2987|sort1|9999999
file2qrs|file2qrs|file2765|sort2|8888888
file2efg|file2efg|file2555|sort3|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2xyz|file2xyz|file2987|sort1|8888888

输出所需的结果。

文件 1 行将是初始行,后面是文件 2 行,其中参考编号匹配并按 # 列排序

输出包含

file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2efg|file2efg|file2555|sort2|9999999
file2tuv|file2tuv|file2666|sort3|9999999
file1def|file1def|file1456|8888888
file2qrs|file2qrs|file2765|sort1|8888888
file2xyz|file2xyz|file2987|sort2|8888888

如有任何帮助和建议,我们将不胜感激。

答案1

如果您有最新版本的 GNU awk,使用 2D 数组并PROCINFO全局设置数组遍历以使用斯特ing(即词法)值工业前在升序结束顺序:

gawk '
  BEGIN {FS = "|"; PROCINFO["sorted_in"] = "@ind_str_asc"} 
  NR==FNR {a[$NF][$(NF-1)] = $0; next} 
  {print; for(i in a[$NF]) print a[$NF][i]}
' File2 File1
file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2efg|file2efg|file2555|sort3|9999999
file1def|file1def|file1456|8888888
file2xyz|file2xyz|file2987|sort1|8888888
file2qrs|file2qrs|file2765|sort2|8888888

对于较旧的 GNU awk,您可以使用asorti来实现相同的目的:

gawk '
  BEGIN{FS="|"} 
  NR==FNR {a[$NF][$(NF-1)] = $0; next} 
  {print; n = asorti(a[$NF],dst,"@ind_str_asc"); for(i=1;i<=n;i++) print a[$NF][dst[i]]}
' File2 File1

如果你想排序数字上基于第(NF-1)th 字段的某些子字符串,那么您可以更改@ind_str_asc为第二个数组索引@ind_num_asc,并将其替换$(NF-1)为经过适当预处理的值 ex。

substr($(NF-1),5)

或使用正则表达式(用于更复杂的密钥提取)

gensub(/[^0-9]*([0-9]+)$/,"\\1","1",$(NF-1))

对于其他 awks,您可以使用一维数组和外部排序:

mawk '
  BEGIN {FS="|"; cmd = "sort -t \| -k4"}
  NR==FNR {a[$NF] = a[$NF] (a[$NF]=="" ? "" : ORS) $0; next}
  {print; print a[$NF] | cmd; close(cmd)}' File2 File1
file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2efg|file2efg|file2555|sort3|9999999
file1def|file1def|file1456|8888888
file2xyz|file2xyz|file2987|sort1|8888888
file2qrs|file2qrs|file2765|sort2|8888888

在这里,您的排序选项将仅限于外部sort函数支持的选项,例如。cmd = "sort -t \| -k4.5,4n"将根据第 4 个字段的第 5 个字符进行数字排序。

相关内容