awk + ​​粘贴来清理路径?

awk + ​​粘贴来清理路径?

.cshrc我在几台机器上的初始化文件中看到过这段代码。我经历了一些 awk 教程试图了解它是如何工作的,但我仍然无法解密它。

setenv PATH `echo $PATH | awk 'NF&&\\!x[$0]++' RS='[:|\n]' | paste -sd:`

它有什么作用?

答案1

反斜杠对我不起作用,但我可以向你解释一下:

echo "$PATH" | awk 'NF && !x[$0]++' RS='[:|\n]'

记录分隔符 ( RS) 设置为字符“:”、“|”之一和换行符。$PATH通常只是一行,元素之间用“:”分隔。这使得 awk 的行为就像路径不是用“:”分隔的,而是每个路径都在自己的行上。

NF表示空行 ( NF == 0) 被忽略。x是一个以路径为下标的关联数组。表示如果大于 0,则!x[$0]++忽略该“行”。结果是每行仅输出一次。x[$0]在第一次运行期间x[$0]增加,因此在接下来的运行中!x[$0]为 false。

此示例显示处理最后一行后所有元素的频率:

echo "a:b:a:c:a:b" |
  awk 'NF && !x[$0]++;END {for (var in x) print var ": " x[var]}' RS='[:|\n]'
a
b
c
a: 3
b: 2
c: 1

答案2

正如所描述的豪克这里的目的是$PATH变量中只包含唯一的元素。

但这不是一个可移植的 awk 脚本,RS通常仅限于单个字符而不是正则表达式。一个更便携的替代方案是这样的:

setenv PATH `printf "%s" "$PATH" | awk '{ sub("/$","") }; x[$0]++ < 1' RS=: | paste -s -d : -`

在 tcsh 中使用 gawk 和 nawk 进行测试。

有几点需要注意:

  • 使用 可以避免无关的换行符printf
  • ,这!意味着历史扩展为 tcsh,可以通过检查值是否小于 1 来替换。
  • 终止路径分隔符被删除sub()

相关内容