awk +クリーンパスに貼り付けますか?

awk +クリーンパスに貼り付けますか?

.cshrc複数のコンピュータの初期化ファイルでこのコードを見たことがあります。私は経験したいくつかの奇妙なチュートリアルそれがどのように機能するかを理解しようとしますが、それでも復号化できません。

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

それは何をしますか?

答え1

バックスラッシュは私には適していませんが、次のように説明できます。

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

レコード区切り文字( RS)は ":", "|"文字と改行文字のいずれかに設定されます。$PATH通常、要素は「:」で区切られた1行です。これにより、awkはパスが ":"で区切られていないように動作しますが、各パスは独自の行にあります。

NF空行(NF == 0)が無視されることを示します。xパスで索引付けされた関連配列。 0より大きい場合、!x[$0]++「行」を無視することを示します。その結果、各行は一度だけ出力されます。x[$0]最初の実行中に増加するため、x[$0]後続の実行では!x[$0]偽です。

この例では、最後の行以降のすべての要素が処理される頻度を示します。

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
  • つまり、!値が1より小さいことを確認して、tcshの履歴拡張を置き換えることができます。
  • 出口パス区切り文字が削除されますsub()

関連情報