【问题标题】:How do i compare alphanumeric characters in non sequential order?如何以非顺序比较字母数字字符?
【发布时间】:2020-08-18 01:02:11
【问题描述】:

目前我正在使用 awk 脚本,它以非顺序比较数字并打印差异。它适用于数字,但如果我有字母数字字符,它似乎效果不佳

在目前的状态下,除了简单地比较数字之外,它还做了两件事:

  1. 目前它考虑数字或字符前的零,并比较绝对值,只忽略数字或字符前的零

  2. 当前如果两个文件中出现多次相同的数字或字符,则输出额外出现的次数

我只是希望脚本能很好地处理字母数字字符,而且目前它似乎只适用于纯数字。有人可以在考虑上述两个条件的同时编辑脚本以获得所需的输出

当前脚本

awk '{k=$0+0} 
       NR==FNR {a[k]++; next} 
       !(k in a && a[k]-->0); 
       END {for(k in a) while(a[k]-->0) print k}' file1 file2

以下示例

猫文件1

1
01
001
8
2B
12
13C
027B
0027B

猫文件2

1
2
08
12
13C
02B
9
27B

预期输出/结果

1
1
2
9
27B

预期输出说明

In file1 : "1" , "01" , "001" evaluates to 1 * 3 times
In file 2 : "1" is present only once
Hence "1" is present twice in result ( 3-1 times )
"2" and "9" are exclusively present in file2 , So obviously both simply form part of output 
In file1 : '027B" , "0027B" evaluates to 27B * 2 times
In file 2 - "27B" is present only once
Hence '27B" is present once in result ( 2 -1 times )

匹配项说明(不属于预期输出的项)

"8" from file1 ( line 4 )is matched with "08" from file2 ( line 3)
"12" from file1 ( line 6) is matched with "12" from file2 ( line 4)
"13C" from file1 (line 7 ) is matched with "13C" from file2 ( line 5 )
"2B" from file1 ( line 5 ) is matched with "02B" from file2 ( line 6 )

最后,预期输出中的项目顺序应按升序排列,如我上面的示例所示,假设上面的示例在预期输出中有 3,它应该垂直读取为 1 1 2 3 9 27B

【问题讨论】:

  • 不清楚,请您详细说明为什么813c 不在您的预期输出中?
  • File1 第 4 行有“8”,file2 第 3 行有“08”,绝对值匹配。 "13C" 出现在 file1 的最后 3 行和 file2 的第 5 行,因此它的匹配项都不是预期输出的一部分
  • 在文件 1-1 中,01,001 计算为 1*3 次,1 出现在文件 2 中一次,因此它构成输出的一部分两次(3-1 次)。 2 和 9 仅存在于 file2 中。 0027B 和 027B 评估为 27B 在文件 1 中出现两次,在文件 2 中出现一次,因此形成一次输出的一部分( 2 -1 次)。我也为其他输出项提供了解释。
  • 能否请您检查一次paste <(awk '{sub(/^0+/,"")} 1' file1) <(awk '{sub(/^0+/,"")} 1' file2) | awk '$1==$2' 并告诉我您是否正在查找此内容?我仍然不清楚你的问题。
  • @RavinderSingh13 收到此错误 - zsh: parse error near `)'

标签: awk


【解决方案1】:

在形成键时删除前导零就足够了(对于零值的特殊情况,如0000):

/^0+$/ { k = 0 }
/[^0]/ { k = $0; sub(/^0*/, "", k) }
NR==FNR {a[k]++; next}
!(k in a && a[k]-->0);
END {for(k in a) while(a[k]-->0) print k}

$ awk -f a.awk file1 file2 
2
9
27B
1
1

重新编辑

如果您只想按数字排序值,请输入 sort:

$ awk -f a.awk file1 file2 | sort -n
1
1
2
3
4
5
9
27B

要按照 file2 中的顺序输出,您可以记住另一个数组中的顺序,然后在 END 块中执行所有打印。此版本将按file2的顺序输出值,最后打印file1中的任何值。

/^0+$/ { k = 0 }
/[^0]/ { k = $0; sub(/^0*/, "", k) }
NR==FNR {a[k]++; next}

{ b[FNR] = k }
!(k in a && a[k]--) { a[k] = 1 }
END { 
  for (i=1; i<=FNR; ++i) {
    k = b[i]
    while(a[k]-->0) print k
  }
  for (k in a) {
    while(a[k]-->0) print k
  }
}

$ awk -f a.awk file1 file2 
1
1
2
9
27B
3
4
5

【讨论】:

  • 如果字母数字字符前面出现零,则此脚本似乎不起作用..我问题的第一点 - 它应该只比较一个数字的绝对值,那个东西应该是保留。我刚刚在有问题的文件 2 中添加了 02B ,现在它没有按预期运行,在输出中列出了 2B 和 02B 。它应该认为 02B 与 2B 匹配,就像它与 02 与 2 匹配一样
  • 查看适用于 2B / 02B 等案例的更新版本
  • 谢谢它现在似乎工作了最后是否可以按类似于我的问题的预期输出的升序对结果进行排序
  • 更新为按照file2中的顺序输出的版本
  • 好的,希望这次我已经理解了一切 :-) 尝试“重新编辑”,让我们看看。
猜你喜欢
  • 2022-01-02
  • 2011-10-26
  • 2013-10-22
  • 2018-05-17
  • 2019-11-04
  • 1970-01-01
  • 2013-12-16
  • 2023-03-12
相关资源
最近更新 更多